• Re: Python-list Digest, Vol 232, Issue 1 (1/2)

    From Christman, Roger Graydon@21:1/5 to Thomas Passin on Mon Jan 2 00:30:51 2023
    Re: Nonetype List

    In my introductory programming course, I have drawn some attention to this behavior regarding mutating lists. Indeed, Python is very consistent with its behavior:

    Any function that mutates a list parameter does not return that list as a return value.
    For one thing, there is no need to return that value, because the caller still owns the list parameter that has been modified.

    But secondly, (and what I find especially important), is that returning the modified list would lead too many program bugs or misunderstandings.

    For example, if append did return the list, you might see this:

    x = [1,2,3]
    y = x.append(4)
    z = y.append(5)

    The principal of 'least surprise' would cause a casual reader to believe that x retains the value of [1,2,3], y would have the value of [1,2,3,4], and z would contain [1,2,3,4,5].

    So it would be very surprising indeed to discover that x contains [1,2,3,4,5], especially after that statement that makes no reference to x. Since append modifies the list in place, returning that list would make x, y, and z all aliases of each other,
    and aliasing is a source of many bugs that are very hard to find.

    So a recommendation that I make to my class (and which coincides with Python behavior), is to NEVER return a modified list as a return value, but only to return lists that were newly created within the function. So to support this principal of 'least
    surprise', the append method above would necessarily create new lists for y and z that are not aliases to x. Why Python does not do that is a very obvious cases of run-time efficiency (constant time to append vs. linear to recreate a new list).

    And as another observation, I have my students review all of the methods defined for the list object, and they are all very consistent. Most of them either define a return value, or modify the list parameter, but almost none do both. The sole
    exception is the pop() function that modified a list and returns a value, but that returned value still is not the modified list, so the aliasing problem will never arise.

    So, I am very happy with this Python language decision -- it allows for the most efficient means to modify a list in place and also very much reduce the danger of aliasing bugs.

    Roger Christman
    Pennsylvania State University
    ________________________________
    From: Python-list <python-list-bounces+dvl=psu.edu@python.org> on behalf of python-list-request@python.org <python-list-request@python.org>
    Sent: Sunday, January 1, 2023 12:00 PM
    To: python-list@python.org <python-list@python.org>
    Subject: Python-list Digest, Vol 232, Issue 1

    Send Python-list mailing list submissions to
    python-list@python.org

    To subscribe or unsubscribe via the World Wide Web, visit
    https://nam10.safelinks.protection.outlook.com/?url=https%3A%2F%2Fmail.python.org%2Fmailman%2Flistinfo%2Fpython-list&data=05%7C01%7Cdvl%40psu.edu%7C744c83fc485a4b1c79db08daec19a436%7C7cf48d453ddb4389a9c1c115526eb52e%7C0%7C0%7C638081892123929669%
    7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000%7C%7C%7C&sdata=etYqO01OszhEpqgjLeKQTMC9b3wT0sc%2FcN8oJo9eEhk%3D&reserved=0
    or, via email, send a message with subject or body 'help' to
    python-list-request@python.org

    You can reach the person managing the list at
    python-list-owner@python.org

    When replying, please edit your Subject line so it is more specific
    than "Re: Contents of Python-list digest..."


    Today's Topics:

    1. Re: NoneType List (Thomas Passin)
    2. Re: NoneType List (MRAB)
    3. Re: NoneType List (dn)
    4. RE: NoneType List (avi.e.gross@gmail.com)
    5. Re: NoneType List (Thomas Passin)
    6. Re: NoneType List (Greg Ewing)
    7. RE: NoneType List (avi.e.gross@gmail.com)
    8. Re: NoneType List (Chris Angelico)
    9. RE: NoneType List (avi.e.gross@gmail.com)
    10. Re: NoneType List (Chris Angelico)
    11. Re: NoneType List (Thomas Passin)


    ----------------------------------------------------------------------

    Message: 1
    Date: Sat, 31 Dec 2022 12:07:25 -0500
    From: Thomas Passin <list1@tompassin.net>
    To: python-list@python.org
    Subject: Re: NoneType List
    Message-ID: <3eb7480c-88f7-72cf-af66-c0072928bf3f@tompassin.net>
    Content-Type: text/plain; charset=UTF-8; format=flowed

    Oops, my reply got lost somehow. Here it is:

    Everyone's answer to date has been too complicated. What is going on is
    that list.append() changes the list in place. It returns nothing. If
    you want to append an item and then assign the result to a new list, you
    have to do just that:

    l1.append(item)
    # If we want a *copy* of the appended list:
    l2 = l1[:] # Changes to l2 will not change l1

    # If we want another name for the appended list:
    l2 = l1 # Changes to l2 will change l1 since they are the same object

    list.sort() also operates in place. There is a function sorted() that
    returns the sorted list (without changing the original list).

    The same thing is true of set.add(). The set is changed in place, and
    nothing is returned.

    On 12/31/2022 10:50 AM, Thomas Passin wrote:
    Happy New Year, everybody!
    I'm new in the Python List, new in Python world, and new in coding.
    A few days (weeks?) ago, I faced a problem trying to write a program for an exercise. I asked for help and nobody answered.
    In the meantime, I found a part of the solution, but a part still remains a mystery for me. Please run this small snippet, and help.
    Thanks

    a = [1, 2]
    print()

    print("a ==", a)
    print("type(a) is", type(a))

    b = a.append(3)
    print("\nb =", "a.append(3)")
    print("b ==", b)
    print("type(b) is", type(b))

    c = ['1', '2']
    print("\nc ==", c)
    print("type(c) is", type(c))

    d = c.append('3')
    print("\nd =", "c.append('3')")
    print("d ==", d)
    print("type(d) is", type(d))

    """
    I mean: why b = a.append(something) is the None type, and how to make a new list
    that contains all the items from a and some new items?
    I wasn't able to solve it in a few hours :(
    Now I know:
    """

    crta = '='
    print('\n', 4 * ' ', crta * (len('The solution:')), sep='')
    print(3 * ' ', 'The solution:')
    print(4 * ' ', crta * (len('The solution:')), sep='')
    print('\nThe solution is the slice, an element of Python syntax that
    allows')
    print('to make a brand new copy of a list, or parts of a list.')
    print('The slice actually copies the list\'s contents, not the list\'s name:')

    print()
    a = [1, 2]
    print("a ==", a)
    print("type(a) is", type(a))

    b = a[:]
    print("\nb = a[:]")
    print("b ==", b)
    b.append(3)
    print("\nb =", "b.append(3)")
    print("b ==", b)
    print("type(b) is", type(b))
    print("\na ==", a)

    print('But I still don't know why "b = a.append(something)" is the None type.')
    print('Is there anybody out there?!')



    ------------------------------

    Message: 2
    Date: Sat, 31 Dec 2022 17:37:39 +0000
    From: MRAB <python@mrabarnett.plus.com>
    To: python-list@python.org
    Subject: Re: NoneType List
    Message-ID: <2321d9bc-5eb3-c1b9-0425-020b54dd39e8@mrabarnett.plus.com> Content-Type: text/plain; charset=UTF-8; format=flowed

    On 2022-12-31 05:45, Goran Ikac wrote:
    Happy New Year, everybody!
    I'm new in the Python List, new in Python world, and new in coding.
    A few days (weeks?) ago, I faced a problem trying to write a program for an exercise. I asked for help and nobody answered.
    In the meantime, I found a part of the solution, but a part still remains a mystery for me. Please run this small snippet, and help.
    Thanks

    a = [1, 2]
    print()

    print("a ==", a)
    print("type(a) is", type(a))

    b = a.append(3)
    print("\nb =", "a.append(3)")
    print("b ==", b)
    print("type(b) is", type(b))

    c = ['1', '2']
    print("\nc ==", c)
    print("type(c) is", type(c))

    d = c.append('3')
    print("\nd =", "c.append('3')")
    print("d ==", d)
    print("type(d) is", type(d))

    """
    I mean: why b = a.append(something) is the None type, and how to make a new list
    that contains all the items from a and some new items?
    I wasn't able to solve it in a few hours :(
    Now I know:
    """

    crta = '='
    print('\n', 4 * ' ', crta * (len('The solution:')), sep='')
    print(3 * ' ', 'The solution:')
    print(4 * ' ', crta * (len('The solution:')), sep='')
    print('\nThe solution is the slice, an element of Python syntax that
    allows')
    print('to make a brand new copy of a list, or parts of a list.')
    print('The slice actually copies the list\'s contents, not the list\'s name:')

    print()
    a = [1, 2]
    print("a ==", a)
    print("type(a) is", type(a))

    b = a[:]
    print("\nb = a[:]")
    print("b ==", b)
    b.append(3)
    print("\nb =", "b.append(3)")
    print("b ==", b)
    print("type(b) is", type(b))
    print("\na ==", a)

    print('But I still don't know why "b = a.append(something)" is the None type.')
    print('Is there anybody out there?!')

    Methods that modify in-place usually return None. "a.append(something)" modifies (appends to) the list 'a' and returns None.

    If you want to a new line with something at the end try "b = a +
    [something]".



    ------------------------------

    Message: 3
    Date: Sun, 1 Jan 2023 09:58:35 +1300
    From: dn <PythonList@DancesWithMice.info>
    To: python-list@python.org
    Subject: Re: NoneType List
    Message-ID: <2b238dce-3e9f-9bee-27a0-d163cb6c7cef@DancesWithMice.info> Content-Type: text/plain; charset=UTF-8; format=flowed

    On 31/12/2022 18.45, Goran Ikac wrote:
    ...
    A few days (weeks?) ago, I faced a problem trying to write a program for an exercise. I asked for help and nobody answered.

    Looking back over the last six months of List-Archives, your name does
    not appear against a single post. This may explain why "nobody answered".

    However, ten hours after the above/first message, you posted again. This
    time as "Thomas Passin". That was followed an hour-or-so later, with a reply-to-self saying: "Everyone's answer to date has been too
    complicated", and then basically repeating the information
    previously-provided by a number of contributors.

    It then goes on to talk about copying, sorting, adding, and even sets.
    Much of which you had earlier said: "I know". Was there a further
    question in there?

    Which part of which answer did you find "too complicated"?

    Did you try the experiments suggested, and read the references-provided?

    Please ask a further question detailing what you have understood, and
    what is still mystifying. Folk here endeavor to be helpful (see also,
    earlier reference to the Python-Tutor list).

    When asking a question here, please try to reduce the problem to its
    simplest form, so that you're not asking volunteers to read
    multiple-screens of irrelevant code. It will help to ask one question at
    a time, or to carefully separate multiple questions.

    Yes, this can be difficult when one is learning. That said, we all
    started somewhere and are happy to help you to become a valued colleague!

    --
    Regards,
    =dn


    ------------------------------

    Message: 4
    Date: Sat, 31 Dec 2022 17:36:59 -0500
    From: <avi.e.gross@gmail.com>
    To: <python-list@python.org>
    Subject: RE: NoneType List
    Message-ID: <006501d91d68$6538dd10$2faa9730$@gmail.com>
    Content-Type: text/plain; charset="us-ascii"

    It depends on what people consider too complicated.

    I find it a tad complicated when someone posts using two different ID, and
    then wonders ...

    The question related to taking a list and extending it and using the result
    in an assignment statement.

    There were several inter-related questions people responded to.

    One was asking why something did not work as expected. Several answers
    pointed out it was because it was not designed the way expected and reading
    the manual page or other reference material would help explain that you need
    to use code the way it was intended and not as you wish it. Other aspects of similar code that do what you expect were shown and you could pick any you liked.

    A second question some were answering is various ways to get the
    functionality wanted. Some were simple enough like using "+" and others did seem complex as they showed many variations on copying an object or how to
    make a subclass that effectively substitutes a method that returns the internally changed object.

    And, of course, we had the philosophical question of why the feature was designed to not return anything (well, NULL) rather than return the changed object. Returning nothing is arguably slightly more efficient in the many
    cases where the return value is simply ignored and thus tossed. But as mentioned, it would be nice for some purposes, including chaining, to be
    able to write something like

    result = lst.add_ret("item").sort_ret()

    As mentioned, this can still be easily done using something like:

    result = sorted(lst + "item")

    -----Original Message-----
    From: Python-list <python-list-bounces+avi.e.gross=gmail.com@python.org> On Behalf Of dn
    Sent: Saturday, December 31, 2022 3:59 PM
    To: python-list@python.org
    Subject: Re: NoneType List

    On 31/12/2022 18.45, Goran Ikac wrote:
    ...
    A few days (weeks?) ago, I faced a problem trying to write a program
    for an exercise. I asked for help and nobody answered.

    Looking back over the last six months of List-Archives, your name does not appear against a single post. This may explain why "nobody answered".

    However, ten hours after the above/first message, you posted again. This
    time as "Thomas Passin". That was followed an hour-or-so later, with a reply-to-self saying: "Everyone's answer to date has been too complicated",
    and then basically repeating the information previously-provided by a number
    of contributors.

    It then goes on to talk about copying, sorting, adding, and even sets.
    Much of which you had earlier said: "I know". Was there a further question
    in there?

    Which part of which answer did you find "too complicated"?

    Did you try the experiments suggested, and read the references-provided?

    Please ask a further question detailing what you have understood, and what
    is still mystifying. Folk here endeavor to be helpful (see also, earlier reference to the Python-Tutor list).

    When asking a question here, please try to reduce the problem to its
    simplest form, so that you're not asking volunteers to read multiple-screens
    of irrelevant code. It will help to ask one question at a time, or to
    carefully separate multiple questions.

    Yes, this can be difficult when one is learning. That said, we all started somewhere and are happy to help you to become a valued colleague!

    --
    Regards,
    =dn
    -- https://nam10.safelinks.protection.outlook.com/?url=https%3A%2F%2Fmail.python.org%2Fmailman%2Flistinfo%2Fpython-list&data=05%7C01%7Cdvl%40psu.edu%7C744c83fc485a4b1c79db08daec19a436%7C7cf48d453ddb4389a9c1c115526eb52e%7C0%7C0%7C638081892123929669%7CUnknown%
    7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000%7C%7C%7C&sdata=etYqO01OszhEpqgjLeKQTMC9b3wT0sc%2FcN8oJo9eEhk%3D&reserved=0



    ------------------------------

    Message: 5
    Date: Sat, 31 Dec 2022 18:32:04 -0500
    From: Thomas Passin <list1@tompassin.net>
    To: python-list@python.org
    Subject: Re: NoneType List
    Message-ID: <11625e0f-8975-b929-a2ca-e14ed74a19b0@tompassin.net>
    Content-Type: text/plain; charset=UTF-8; format=flowed

    On 12/31/2022 3:58 PM, dn wrote:
    On 31/12/2022 18.45, Goran Ikac wrote:
    ...
    A few days (weeks?) ago, I faced a problem trying to write a program
    for an
    exercise. I asked for help and nobody answered.

    Looking back over the last six months of List-Archives, your name does
    not appear against a single post. This may explain why "nobody answered".

    However, ten hours after the above/first message, you posted again. This
    time as "Thomas Passin".

    That message was probably a mistaken one from me. I had composed a
    reply but through some mental glitch had to re-do it. I managed to send
    it with the only quoted thread but not the reply I had wanted to
    include. So I added my reply and sent it again. It was probably
    confusing, and I'm sorry about that.

    That was followed an hour-or-so later, with a
    reply-to-self saying: "Everyone's answer to date has been too
    complicated", and then basically repeating the information previously-provided by a number of contributors.

    It then goes on to talk about copying, sorting, adding, and even sets.
    Much of which you had earlier said: "I know". Was there a further
    question in there?

    Which part of which answer did you find "too complicated"?

    Did you try the experiments suggested, and read the references-provided?

    Please ask a further question detailing what you have understood, and
    what is still mystifying. Folk here endeavor to be helpful (see also,
    earlier reference to the Python-Tutor list).

    When asking a question here, please try to reduce the problem to its
    simplest form, so that you're not asking volunteers to read
    multiple-screens of irrelevant code. It will help to ask one question at
    a time, or to carefully separate multiple questions.

    Yes, this can be difficult when one is learning. That said, we all
    started somewhere and are happy to help you to become a valued colleague!




    ------------------------------

    Message: 6
    Date: Sun, 1 Jan 2023 13:21:05 +1300
    From: Greg Ewing <greg.ewing@canterbury.ac.nz>
    To: python-list@python.org
    Subject: Re: NoneType List
    Message-ID: <k1c1vkF15cmU1@mid.individual.net>
    Content-Type: text/plain; charset=UTF-8; format=flowed

    On 1/01/23 11:36 am, avi.e.gross@gmail.com wrote:
    And, of course, we had the philosophical question of why the feature was designed to not return anything ... rather than return the changed
    object.

    My understanding is that Guido designed it that way to keep a
    clear separation between mutating and non-mutating methods, and
    to help catch mistakes resulting from mixing them up.

    --
    Greg


    ------------------------------

    Message: 7
    Date: Sat, 31 Dec 2022 22:17:56 -0500
    From: <avi.e.gross@gmail.com>
    To: "'Greg Ewing'" <greg.ewing@canterbury.ac.nz>,
    <python-list@python.org>
    Subject: RE: NoneType List
    Message-ID: <00e601d91d8f$a4e59b20$eeb0d160$@gmail.com>
    Content-Type: text/plain; charset="us-ascii"

    Agreed, there are lots of pro/con arguments and the feature is what it is historically and not trivial to change. Inline changes to an object make
    sense to just be done "silently" and if there are errors, they propagate the usual way.

    As Guido was a major influence at that time, one view was seen as more important and prevailed.

    Had a language like that been created today, I wonder if some designs might have looked a bit different so that some functions could be called with optional arguments that specified what the user wanted returned.

    In particular, besides a function where you add a value returning
    nothing/None, there may be room for other choices and any choice hard-wired
    in would eleicit complaints from others.

    lst.add("Value")

    could also return one of several other things such as a pointer to the
    upgraded object but also of a pointer to the object as it looked before the change (not a serious proposal) or a True/False value specifying if the
    change was able to be completed (such as running out of memory, or the
    addition not being something you can put in the object) or even return what
    was added or how many objects are now in the object at the top level, or how many times the method was called so far!

    I suspect, at the expense of some overhead, you could just add an argument
    to many kinds of methods or even functions such as returning='option' that guides what you want returned, with the default often being what Guido and others currently have set.

    Python already allows functions to return anything they feel like, so this probably would not break many things.

    Of course there are other paths in that direction, such as setting an
    attribute of the list/object first that affects how things get returned but that seems more cumbersome and makes all kinds of errors more likely. Still, that is a path often used by some Python modules where objects are created
    and then tweaked to behave in various ways when later methods are invoked.

    But is any of it needed? The current system generally works fine and we have seen many ways to get other results without tampering with the current implementation.

    This may be yet another example of people who come to python with
    pre-existing bias, such as insisting it work like another language they have used, or wanting the computer to do what they MEANT rather than what they explicitly or implicitly programmed!


    -----Original Message-----
    From: Python-list <python-list-bounces+avi.e.gross=gmail.com@python.org> On Behalf Of Greg Ewing
    Sent: Saturday, December 31, 2022 7:21 PM
    To: python-list@python.org
    Subject: Re: NoneType List

    On 1/01/23 11:36 am, avi.e.gross@gmail.com wrote:
    And, of course, we had the philosophical question of why the feature
    was designed to not return anything ... rather than return the changed object.

    My understanding is that Guido designed it that way to keep a clear
    separation between mutating and non-mutating methods, and to help catch mistakes resulting from mixing them up.

    --
    Greg
    -- https://nam10.safelinks.protection.outlook.com/?url=https%3A%2F%2Fmail.python.org%2Fmailman%2Flistinfo%2Fpython-list&data=05%7C01%7Cdvl%40psu.edu%7C744c83fc485a4b1c79db08daec19a436%7C7cf48d453ddb4389a9c1c115526eb52e%7C0%7C0%7C638081892123929669%7CUnknown%
    7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000%7C%7C%7C&sdata=etYqO01OszhEpqgjLeKQTMC9b3wT0sc%2FcN8oJo9eEhk%3D&reserved=0



    ------------------------------

    Message: 8
    Date: Sun, 1 Jan 2023 14:23:13 +1100
    From: Chris Angelico <rosuav@gmail.com>
    To: python-list@python.org
    Subject: Re: NoneType List
    Message-ID:
    <CAPTjJmq=n0=B7fHvtydTwe0eZ+GVxTzGH-3TJDX6E9PyVHsEnQ@mail.gmail.com> Content-Type: text/plain; charset="UTF-8"

    On Sun, 1 Jan 2023 at 14:19, <avi.e.gross@gmail.com> wrote:
    Had a language like that been created today, I wonder if some designs might have looked a bit different so that some functions could be called with optional arguments that specified what the user wanted returned.

    Frankly, I doubt it. While you can argue "returning self is more
    useful" vs "returning None is more clear if you get it wrong", having
    options does NOT improve things, and just makes everything more
    complicated, slower, harder to comprehend, and generally worse to work
    with.

    A language should have some sort of consistent behaviour and stick to
    it. If that's not possible, an object type should at least have that.

    ChrisA


    ------------------------------

    Message: 9
    Date: Sat, 31 Dec 2022 23:16:10 -0500
    From: <avi.e.gross@gmail.com>
    To: "'Chris Angelico'" <rosuav@gmail.com>, <python-list@python.org> Subject: RE: NoneType List
    Message-ID: <00fd01d91d97$c78994d0$569cbe70$@gmail.com>
    Content-Type: text/plain; charset="us-ascii"

    Chris,

    There is much to say about consistent behavior as compared to flexibility
    and convenience.

    I have seen other languages provide functions for example, where the result can vary and often cause confusion. R had a function that would sometimes notice the result could be simplified and return that. Guess what? It caused lots of problems and an option was added that said it should NOT simplify
    and always return the same kind of thing.

    Consider what happens if a calculation that returned a matrix would decide
    that is there was only one columns, it would return a vector/array/whatever
    as a one-dimensional result and if the calculation produced a 1 by 1 matrix,
    it would simply return a scalar value!

    But it may be a feature you want in some cases, albeit rarely when the
    results of the function are fed into something that is not expecting it. Various forms of polymorphism can be helpful but can also be very confusing.

    Some solutions are what I have described in earlier messages and some
    languages blur distinctions. Again, in R, there may not be a scalar as all
    you have is a vector of length one. But matrices even of 1-D are not vectors and I have had to interconvert between them to make some code run.

    I am not making comparisons in the sense that nothing other languages choose
    to do is binding on what Python should do. Still, I think it is wrong to suggest that it does not often do partially ambiguous things from some perspective. Many functions will take a variety of arguments and return something reasonable but different each time.

    As a dumb example, what does a simple function like max() return if fed just integers, just floating point or a combination of both? It seems to return whatever type the maximum indicates. But it also accepts characters and
    sorts them appropriately returning type 'str' and probably accepts and
    returns all kinds of objects if you specify a key function.

    Is that so much different than we are discussing in that there isn't any absolute consistency and things can go various ways in terms of return
    value? Heck, I can even make max() return None!


    -----Original Message-----
    From: Python-list <python-list-bounces+avi.e.gross=gmail.com@python.org> On Behalf Of Chris Angelico
    Sent: Saturday, December 31, 2022 10:23 PM
    To: python-list@python.org
    Subject: Re: NoneType List

    On Sun, 1 Jan 2023 at 14:19, <avi.e.gross@gmail.com> wrote:
    Had a language like that been created today, I wonder if some designs
    might have looked a bit different so that some functions could be
    called with optional arguments that specified what the user wanted
    returned.

    Frankly, I doubt it. While you can argue "returning self is more useful" vs "returning None is more clear if you get it wrong", having options does NOT improve things, and just makes everything more complicated, slower, harder
    to comprehend, and generally worse to work with.

    A language should have some sort of consistent behaviour and stick to it. If that's not possible, an object type should at least have that.

    ChrisA
    -- https://nam10.safelinks.protection.outlook.com/?url=https%3A%2F%2Fmail.python.org%2Fmailman%2Flistinfo%2Fpython-list&data=05%7C01%7Cdvl%40psu.edu%7C744c83fc485a4b1c79db08daec19a436%7C7cf48d453ddb4389a9c1c115526eb52e%7C0%7C0%7C638081892123929669%7CUnknown%
    7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000%7C%7C%7C&sdata=etYqO01OszhEpqgjLeKQTMC9b3wT0sc%2FcN8oJo9eEhk%3D&reserved=0



    ------------------------------

    Message: 10
    Date: Sun, 1 Jan 2023 15:23:59 +1100
    From: Chris Angelico <rosuav@gmail.com>
    To: python-list@python.org
    Subject: Re: NoneType List
    Message-ID:
    <CAPTjJmqqGLqE=FepRMM1P95E3eGv5Qnq_=BfsGJNXuucLH6wMg@mail.gmail.com> Content-Type: text/plain; charset="UTF-8"

    On Sun, 1 Jan 2023 at 15:16, <avi.e.gross@gmail.com> wrote:

    Chris,

    There is much to say about consistent behavior as compared to flexibility
    and convenience.

    I have seen other languages provide functions for example, where the result can vary and often cause confusion. R had a function that would sometimes notice the result could be simplified and return that. Guess what? It caused lots of problems and an option was added that said it should NOT simplify
    and always return the same kind of thing.

    The option was presumably added because backward compatibility is
    important, but it would have been better to not need the option in the
    first place.

    As a dumb example, what does a simple function like max() return if fed just integers, just floating point or a combination of both? It seems to return whatever type the maximum indicates. But it also accepts characters and
    sorts them appropriately returning type 'str' and probably accepts and returns all kinds of objects if you specify a key function.

    Is that so much different than we are discussing in that there isn't any absolute consistency and things can go various ways in terms of return
    value? Heck, I can even make max() return None!


    ... yes? So? It still always returns the largest item in the list, for
    some definition of "largest". You'll never have that value returned
    wrapped up in a single-element list, though.

    ChrisA


    ------------------------------

    Message: 11
    Date: Sun, 1 Jan 2023 08:11:02 -0500
    From: Thomas Passin <list1@tompassin.net>
    To: python-list@python.org
    Subject: Re: NoneType List
    Message-ID: <71caabcd-65a0-8b3f-a971-79cd3f4415e1@tompassin.net>
    Content-Type: text/plain; charset=UTF-8; format=flowed

    On 12/31/2022 10:17 PM, avi.e.gross@gmail.com wrote:
    Agreed, there are lots of pro/con arguments and the feature is what it is historically and not trivial to change. Inline changes to an object make sense to just be done "silently" and if there are errors, they propagate the usual way.

    As Guido was a major influence at that time, one view was seen as more important and prevailed.

    Had a language like that been created today, I wonder if some designs might have looked a bit different so that some functions could be called with optional arguments that specified what the user wanted returned.

    Guido had been working on the ABC language for some years before he
    developed Python. ABC was intended mainly as a teaching and prototyping language. Guido probably had a good sense of what things worked well
    and what didn't in that usage. IIRC, Python did not originally have
    classes or instances, and a "fluent" style of programming probably
    wasn't in use yet. Having an object return itself after an operation is
    useful (mostly, perhaps) for fluent programming (that is, the style
    where one can write X.method1().method2().method3() ...).

    In particular, besides a function where you add a value returning nothing/None, there may be room for other choices and any choice hard-wired in would eleicit complaints from others.

    lst.add("Value")

    could also return one of several other things such as a pointer to the upgraded object but also of a pointer to the object as it looked before the change (not a serious proposal) or a True/False value specifying if the change was able to be completed (such as running out of memory, or the addition not being something you can put in the object) or even return what was added or how many objects are now in the object at the top level, or how many times the method was called so far!

    I suspect, at the expense of some overhead, you could just add an argument
    to many kinds of methods or even functions such as returning='option' that guides what you want returned, with the default often being what Guido and others currently have set.

    Python already allows functions to return anything they feel like, so this probably would not break many things.

    Of course there are other paths in that direction, such as setting an attribute of the list/object first that affects how things get returned but that seems more cumbersome and makes all kinds of errors more likely. Still, that is a path often used by some Python modules where objects are created and then tweaked to behave in various ways when later methods are invoked.

    But is any of it needed? The current system generally works fine and we have seen many ways to get other results without tampering with the current implementation.

    This may be yet another example of people who come to python with pre-existing bias, such as insisting it work like another language they have used, or wanting the computer to do what they MEANT rather than what they explicitly or implicitly programmed!


    -----Original Message-----
    From: Python-list <python-list-bounces+avi.e.gross=gmail.com@python.org> On Behalf Of Greg Ewing
    Sent: Saturday, December 31, 2022 7:21 PM
    To: python-list@python.org
    Subject: Re: NoneType List

    On 1/01/23 11:36 am, avi.e.gross@gmail.com wrote:
    And, of course, we had the philosophical question of why the feature
    was designed to not return anything ... rather than return the changed
    object.

    My understanding is that Guido designed it that way to keep a clear

    [continued in next message]

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From avi.e.gross@gmail.com@21:1/5 to Thomas Passin on Mon Jan 2 01:13:58 2023
    Well explained, Roger.

    Your explanation reminds me why some languages very deliberately do not want the C operators of pre/post increment/decrement.

    Similar to your argument, code in C like:

    Y = X++
    Or
    Y = ++X

    And similarly the -- versions, have a sort of side effect of changing X
    either before or after the "value" is used.

    Code like:
    X += 1
    Or
    X = X + 1
    Followed by
    Y = X

    Can be longer but a tad clearer, as is code like:
    Y = X
    X -= 1

    I have seen code in languages that support this that can take some head scratching to figure out when combinations using parentheses and multiple instances of ++/-- are used pre and/or post.

    Then again, Python added the Walrus operator recently that also allows a
    kind of change within an expression that can be quite useful but can be
    viewed as a sort of change to an object and a return of the new value.

    x = 1
    y = (x := 5)
    y
    5
    z = (x := x * 2) + (x := x + 1)
    z
    21
    x
    11

    I posit constructs such as the above may have similarities to changing an object and returning the new updated object. Maybe not the same but ...

    Avi



    -----Original Message-----
    From: Python-list <python-list-bounces+avi.e.gross=gmail.com@python.org> On Behalf Of Christman, Roger Graydon
    Sent: Sunday, January 1, 2023 7:31 PM
    To: python-list@python.org
    Subject: Re: Python-list Digest, Vol 232, Issue 1

    Re: Nonetype List

    In my introductory programming course, I have drawn some attention to this behavior regarding mutating lists. Indeed, Python is very consistent with
    its behavior:

    Any function that mutates a list parameter does not return that list as a return value.
    For one thing, there is no need to return that value, because the caller
    still owns the list parameter that has been modified.

    But secondly, (and what I find especially important), is that returning the modified list would lead too many program bugs or misunderstandings.

    For example, if append did return the list, you might see this:

    x = [1,2,3]
    y = x.append(4)
    z = y.append(5)

    The principal of 'least surprise' would cause a casual reader to believe
    that x retains the value of [1,2,3], y would have the value of [1,2,3,4],
    and z would contain [1,2,3,4,5].

    So it would be very surprising indeed to discover that x contains
    [1,2,3,4,5], especially after that statement that makes no reference to x. Since append modifies the list in place, returning that list would make x,
    y, and z all aliases of each other, and aliasing is a source of many bugs
    that are very hard to find.

    So a recommendation that I make to my class (and which coincides with Python behavior), is to NEVER return a modified list as a return value, but only to return lists that were newly created within the function. So to support
    this principal of 'least surprise', the append method above would
    necessarily create new lists for y and z that are not aliases to x. Why Python does not do that is a very obvious cases of run-time efficiency (constant time to append vs. linear to recreate a new list).

    And as another observation, I have my students review all of the methods defined for the list object, and they are all very consistent. Most of
    them either define a return value, or modify the list parameter, but almost none do both. The sole exception is the pop() function that modified a
    list and returns a value, but that returned value still is not the modified list, so the aliasing problem will never arise.

    So, I am very happy with this Python language decision -- it allows for the most efficient means to modify a list in place and also very much reduce the danger of aliasing bugs.

    Roger Christman
    Pennsylvania State University
    ________________________________
    From: Python-list <python-list-bounces+dvl=psu.edu@python.org> on behalf of python-list-request@python.org <python-list-request@python.org>
    Sent: Sunday, January 1, 2023 12:00 PM
    To: python-list@python.org <python-list@python.org>
    Subject: Python-list Digest, Vol 232, Issue 1

    Send Python-list mailing list submissions to
    python-list@python.org

    To subscribe or unsubscribe via the World Wide Web, visit

    https://nam10.safelinks.protection.outlook.com/?url=https%3A%2F%2Fmail.pytho n.org%2Fmailman%2Flistinfo%2Fpython-list&data=05%7C01%7Cdvl%40psu.edu%7C744c 83fc485a4b1c79db08daec19a436%7C7cf48d453ddb4389a9c1c115526eb52e%7C0%7C0%7C63 8081892123929669%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzI iLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000%7C%7C%7C&sdata=etYqO01OszhEpqgjLeKQTM C9b3wT0sc%2FcN8oJo9eEhk%3D&reserved=0
    or, via email, send a message with subject or body 'help' to
    python-list-request@python.org

    You can reach the person managing the list at
    python-list-owner@python.org

    When replying, please edit your Subject line so it is more specific than
    "Re: Contents of Python-list digest..."


    Today's Topics:

    1. Re: NoneType List (Thomas Passin)
    2. Re: NoneType List (MRAB)
    3. Re: NoneType List (dn)
    4. RE: NoneType List (avi.e.gross@gmail.com)
    5. Re: NoneType List (Thomas Passin)
    6. Re: NoneType List (Greg Ewing)
    7. RE: NoneType List (avi.e.gross@gmail.com)
    8. Re: NoneType List (Chris Angelico)
    9. RE: NoneType List (avi.e.gross@gmail.com)
    10. Re: NoneType List (Chris Angelico)
    11. Re: NoneType List (Thomas Passin)


    ----------------------------------------------------------------------

    Message: 1
    Date: Sat, 31 Dec 2022 12:07:25 -0500
    From: Thomas Passin <list1@tompassin.net>
    To: python-list@python.org
    Subject: Re: NoneType List
    Message-ID: <3eb7480c-88f7-72cf-af66-c0072928bf3f@tompassin.net>
    Content-Type: text/plain; charset=UTF-8; format=flowed

    Oops, my reply got lost somehow. Here it is:

    Everyone's answer to date has been too complicated. What is going on is
    that list.append() changes the list in place. It returns nothing. If you
    want to append an item and then assign the result to a new list, you have to
    do just that:

    l1.append(item)
    # If we want a *copy* of the appended list:
    l2 = l1[:] # Changes to l2 will not change l1

    # If we want another name for the appended list:
    l2 = l1 # Changes to l2 will change l1 since they are the same object

    list.sort() also operates in place. There is a function sorted() that
    returns the sorted list (without changing the original list).

    The same thing is true of set.add(). The set is changed in place, and
    nothing is returned.

    On 12/31/2022 10:50 AM, Thomas Passin wrote:
    Happy New Year, everybody!
    I'm new in the Python List, new in Python world, and new in coding.
    A few days (weeks?) ago, I faced a problem trying to write a program
    for an exercise. I asked for help and nobody answered.
    In the meantime, I found a part of the solution, but a part still
    remains a mystery for me. Please run this small snippet, and help.
    Thanks

    a = [1, 2]
    print()

    print("a ==", a)
    print("type(a) is", type(a))

    b = a.append(3)
    print("\nb =", "a.append(3)")
    print("b ==", b)
    print("type(b) is", type(b))

    c = ['1', '2']
    print("\nc ==", c)
    print("type(c) is", type(c))

    d = c.append('3')
    print("\nd =", "c.append('3')")
    print("d ==", d)
    print("type(d) is", type(d))

    """
    I mean: why b = a.append(something) is the None type, and how to make
    a new list that contains all the items from a and some new items?
    I wasn't able to solve it in a few hours :( Now I know:
    """

    crta = '='
    print('\n', 4 * ' ', crta * (len('The solution:')), sep='')
    print(3 * ' ', 'The solution:')
    print(4 * ' ', crta * (len('The solution:')), sep='') print('\nThe
    solution is the slice, an element of Python syntax that
    allows')
    print('to make a brand new copy of a list, or parts of a list.')
    print('The slice actually copies the list\'s contents, not the list\'s name:')

    print()
    a = [1, 2]
    print("a ==", a)
    print("type(a) is", type(a))

    b = a[:]
    print("\nb = a[:]")
    print("b ==", b)
    b.append(3)
    print("\nb =", "b.append(3)")
    print("b ==", b)
    print("type(b) is", type(b))
    print("\na ==", a)

    print('But I still don't know why "b = a.append(something)" is the
    None
    type.')
    print('Is there anybody out there?!')



    ------------------------------

    Message: 2
    Date: Sat, 31 Dec 2022 17:37:39 +0000
    From: MRAB <python@mrabarnett.plus.com>
    To: python-list@python.org
    Subject: Re: NoneType List
    Message-ID: <2321d9bc-5eb3-c1b9-0425-020b54dd39e8@mrabarnett.plus.com> Content-Type: text/plain; charset=UTF-8; format=flowed

    On 2022-12-31 05:45, Goran Ikac wrote:
    Happy New Year, everybody!
    I'm new in the Python List, new in Python world, and new in coding.
    A few days (weeks?) ago, I faced a problem trying to write a program
    for an exercise. I asked for help and nobody answered.
    In the meantime, I found a part of the solution, but a part still
    remains a mystery for me. Please run this small snippet, and help.
    Thanks

    a = [1, 2]
    print()

    print("a ==", a)
    print("type(a) is", type(a))

    b = a.append(3)
    print("\nb =", "a.append(3)")
    print("b ==", b)
    print("type(b) is", type(b))

    c = ['1', '2']
    print("\nc ==", c)
    print("type(c) is", type(c))

    d = c.append('3')
    print("\nd =", "c.append('3')")
    print("d ==", d)
    print("type(d) is", type(d))

    """
    I mean: why b = a.append(something) is the None type, and how to make
    a new list that contains all the items from a and some new items?
    I wasn't able to solve it in a few hours :( Now I know:
    """

    crta = '='
    print('\n', 4 * ' ', crta * (len('The solution:')), sep='')
    print(3 * ' ', 'The solution:')
    print(4 * ' ', crta * (len('The solution:')), sep='') print('\nThe
    solution is the slice, an element of Python syntax that
    allows')
    print('to make a brand new copy of a list, or parts of a list.')
    print('The slice actually copies the list\'s contents, not the list\'s name:')

    print()
    a = [1, 2]
    print("a ==", a)
    print("type(a) is", type(a))

    b = a[:]
    print("\nb = a[:]")
    print("b ==", b)
    b.append(3)
    print("\nb =", "b.append(3)")
    print("b ==", b)
    print("type(b) is", type(b))
    print("\na ==", a)

    print('But I still don't know why "b = a.append(something)" is the
    None
    type.')
    print('Is there anybody out there?!')

    Methods that modify in-place usually return None. "a.append(something)" modifies (appends to) the list 'a' and returns None.

    If you want to a new line with something at the end try "b = a +
    [something]".



    ------------------------------

    Message: 3
    Date: Sun, 1 Jan 2023 09:58:35 +1300
    From: dn <PythonList@DancesWithMice.info>
    To: python-list@python.org
    Subject: Re: NoneType List
    Message-ID: <2b238dce-3e9f-9bee-27a0-d163cb6c7cef@DancesWithMice.info> Content-Type: text/plain; charset=UTF-8; format=flowed

    On 31/12/2022 18.45, Goran Ikac wrote:
    ...
    A few days (weeks?) ago, I faced a problem trying to write a program
    for an exercise. I asked for help and nobody answered.

    Looking back over the last six months of List-Archives, your name does not appear against a single post. This may explain why "nobody answered".

    However, ten hours after the above/first message, you posted again. This
    time as "Thomas Passin". That was followed an hour-or-so later, with a reply-to-self saying: "Everyone's answer to date has been too complicated",
    and then basically repeating the information previously-provided by a number
    of contributors.

    It then goes on to talk about copying, sorting, adding, and even sets.
    Much of which you had earlier said: "I know". Was there a further question
    in there?

    Which part of which answer did you find "too complicated"?

    Did you try the experiments suggested, and read the references-provided?

    Please ask a further question detailing what you have understood, and what
    is still mystifying. Folk here endeavor to be helpful (see also, earlier reference to the Python-Tutor list).

    When asking a question here, please try to reduce the problem to its
    simplest form, so that you're not asking volunteers to read multiple-screens
    of irrelevant code. It will help to ask one question at a time, or to
    carefully separate multiple questions.

    Yes, this can be difficult when one is learning. That said, we all started somewhere and are happy to help you to become a valued colleague!

    --
    Regards,
    =dn


    ------------------------------

    Message: 4
    Date: Sat, 31 Dec 2022 17:36:59 -0500
    From: <avi.e.gross@gmail.com>
    To: <python-list@python.org>
    Subject: RE: NoneType List
    Message-ID: <006501d91d68$6538dd10$2faa9730$@gmail.com>
    Content-Type: text/plain; charset="us-ascii"

    It depends on what people consider too complicated.

    I find it a tad complicated when someone posts using two different ID, and
    then wonders ...

    The question related to taking a list and extending it and using the result
    in an assignment statement.

    There were several inter-related questions people responded to.

    One was asking why something did not work as expected. Several answers
    pointed out it was because it was not designed the way expected and reading
    the manual page or other reference material would help explain that you need
    to use code the way it was intended and not as you wish it. Other aspects of similar code that do what you expect were shown and you could pick any you liked.

    A second question some were answering is various ways to get the
    functionality wanted. Some were simple enough like using "+" and others did seem complex as they showed many variations on copying an object or how to
    make a subclass that effectively substitutes a method that returns the internally changed object.

    And, of course, we had the philosophical question of why the feature was designed to not return anything (well, NULL) rather than return the changed object. Returning nothing is arguably slightly more efficient in the many
    cases where the return value is simply ignored and thus tossed. But as mentioned, it would be nice for some purposes, including chaining, to be
    able to write something like

    result = lst.add_ret("item").sort_ret()

    As mentioned, this can still be easily done using something like:

    result = sorted(lst + "item")

    -----Original Message-----
    From: Python-list <python-list-bounces+avi.e.gross=gmail.com@python.org> On Behalf Of dn
    Sent: Saturday, December 31, 2022 3:59 PM
    To: python-list@python.org
    Subject: Re: NoneType List

    On 31/12/2022 18.45, Goran Ikac wrote:
    ...
    A few days (weeks?) ago, I faced a problem trying to write a program
    for an exercise. I asked for help and nobody answered.

    Looking back over the last six months of List-Archives, your name does not appear against a single post. This may explain why "nobody answered".

    However, ten hours after the above/first message, you posted again. This
    time as "Thomas Passin". That was followed an hour-or-so later, with a reply-to-self saying: "Everyone's answer to date has been too complicated",
    and then basically repeating the information previously-provided by a number
    of contributors.

    It then goes on to talk about copying, sorting, adding, and even sets.
    Much of which you had earlier said: "I know". Was there a further question
    in there?

    Which part of which answer did you find "too complicated"?

    Did you try the experiments suggested, and read the references-provided?

    Please ask a further question detailing what you have understood, and what
    is still mystifying. Folk here endeavor to be helpful (see also, earlier reference to the Python-Tutor list).

    When asking a question here, please try to reduce the problem to its
    simplest form, so that you're not asking volunteers to read multiple-screens
    of irrelevant code. It will help to ask one question at a time, or to
    carefully separate multiple questions.

    Yes, this can be difficult when one is learning. That said, we all started somewhere and are happy to help you to become a valued colleague!

    --
    Regards,
    =dn
    --
    https://nam10.safelinks.protection.outlook.com/?url=https%3A%2F%2Fmail.pytho n.org%2Fmailman%2Flistinfo%2Fpython-list&data=05%7C01%7Cdvl%40psu.edu%7C744c 83fc485a4b1c79db08daec19a436%7C7cf48d453ddb4389a9c1c115526eb52e%7C0%7C0%7C63 8081892123929669%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzI iLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000%7C%7C%7C&sdata=etYqO01OszhEpqgjLeKQTM C9b3wT0sc%2FcN8oJo9eEhk%3D&reserved=0



    ------------------------------

    Message: 5
    Date: Sat, 31 Dec 2022 18:32:04 -0500
    From: Thomas Passin <list1@tompassin.net>
    To: python-list@python.org
    Subject: Re: NoneType List
    Message-ID: <11625e0f-8975-b929-a2ca-e14ed74a19b0@tompassin.net>
    Content-Type: text/plain; charset=UTF-8; format=flowed

    On 12/31/2022 3:58 PM, dn wrote:
    On 31/12/2022 18.45, Goran Ikac wrote:
    ...
    A few days (weeks?) ago, I faced a problem trying to write a program
    for an exercise. I asked for help and nobody answered.

    Looking back over the last six months of List-Archives, your name does
    not appear against a single post. This may explain why "nobody answered".

    However, ten hours after the above/first message, you posted again.
    This time as "Thomas Passin".

    That message was probably a mistaken one from me. I had composed a reply
    but through some mental glitch had to re-do it. I managed to send it with
    the only quoted thread but not the reply I had wanted to include. So I
    added my reply and sent it again. It was probably confusing, and I'm sorry about that.

    That was followed an hour-or-so later, with a reply-to-self saying: "Everyone's answer to date has been too complicated", and then
    basically repeating the information previously-provided by a number of contributors.

    It then goes on to talk about copying, sorting, adding, and even sets.
    Much of which you had earlier said: "I know". Was there a further
    question in there?

    Which part of which answer did you find "too complicated"?

    Did you try the experiments suggested, and read the references-provided?

    Please ask a further question detailing what you have understood, and
    what is still mystifying. Folk here endeavor to be helpful (see also,
    earlier reference to the Python-Tutor list).

    When asking a question here, please try to reduce the problem to its
    simplest form, so that you're not asking volunteers to read
    multiple-screens of irrelevant code. It will help to ask one question
    at a time, or to carefully separate multiple questions.

    Yes, this can be difficult when one is learning. That said, we all
    started somewhere and are happy to help you to become a valued colleague!




    ------------------------------

    Message: 6
    Date: Sun, 1 Jan 2023 13:21:05 +1300
    From: Greg Ewing <greg.ewing@canterbury.ac.nz>
    To: python-list@python.org
    Subject: Re: NoneType List
    Message-ID: <k1c1vkF15cmU1@mid.individual.net>
    Content-Type: text/plain; charset=UTF-8; format=flowed

    On 1/01/23 11:36 am, avi.e.gross@gmail.com wrote:
    And, of course, we had the philosophical question of why the feature
    was designed to not return anything ... rather than return the changed object.

    My understanding is that Guido designed it that way to keep a clear
    separation between mutating and non-mutating methods, and to help catch mistakes resulting from mixing them up.

    --
    Greg


    ------------------------------

    Message: 7
    Date: Sat, 31 Dec 2022 22:17:56 -0500
    From: <avi.e.gross@gmail.com>
    To: "'Greg Ewing'" <greg.ewing@canterbury.ac.nz>,
    <python-list@python.org>
    Subject: RE: NoneType List
    Message-ID: <00e601d91d8f$a4e59b20$eeb0d160$@gmail.com>
    Content-Type: text/plain; charset="us-ascii"

    Agreed, there are lots of pro/con arguments and the feature is what it is historically and not trivial to change. Inline changes to an object make
    sense to just be done "silently" and if there are errors, they propagate the usual way.

    As Guido was a major influence at that time, one view was seen as more important and prevailed.

    Had a language like that been created today, I wonder if some designs might have looked a bit different so that some functions could be called with optional arguments that specified what the user wanted returned.

    In particular, besides a function where you add a value returning
    nothing/None, there may be room for other choices and any choice hard-wired
    in would eleicit complaints from others.

    lst.add("Value")

    could also return one of several other things such as a pointer to the
    upgraded object but also of a pointer to the object as it looked before the change (not a serious proposal) or a True/False value specifying if the
    change was able to be completed (such as running out of memory, or the
    addition not being something you can put in the object) or even return what
    was added or how many objects are now in the object at the top level, or how many times the method was called so far!

    I suspect, at the expense of some overhead, you could just add an argument
    to many kinds of methods or even functions such as returning='option' that guides what you want returned, with the default often being what Guido and others currently have set.

    Python already allows functions to return anything they feel like, so this probably would not break many things.

    Of course there are other paths in that direction, such as setting an
    attribute of the list/object first that affects how things get returned but that seems more cumbersome and makes all kinds of errors more likely. Still, that is a path often used by some Python modules where objects are created
    and then tweaked to behave in various ways when later methods are invoked.

    But is any of it needed? The current system generally works fine and we have seen many ways to get other results without tampering with the current implementation.

    This may be yet another example of people who come to python with
    pre-existing bias, such as insisting it work like another language they have used, or wanting the computer to do what they MEANT rather than what they explicitly or implicitly programmed!


    -----Original Message-----
    From: Python-list <python-list-bounces+avi.e.gross=gmail.com@python.org> On Behalf Of Greg Ewing
    Sent: Saturday, December 31, 2022 7:21 PM
    To: python-list@python.org
    Subject: Re: NoneType List

    On 1/01/23 11:36 am, avi.e.gross@gmail.com wrote:
    And, of course, we had the philosophical question of why the feature
    was designed to not return anything ... rather than return the changed object.

    My understanding is that Guido designed it that way to keep a clear
    separation between mutating and non-mutating methods, and to help catch mistakes resulting from mixing them up.

    --
    Greg
    --
    https://nam10.safelinks.protection.outlook.com/?url=https%3A%2F%2Fmail.pytho n.org%2Fmailman%2Flistinfo%2Fpython-list&data=05%7C01%7Cdvl%40psu.edu%7C744c 83fc485a4b1c79db08daec19a436%7C7cf48d453ddb4389a9c1c115526eb52e%7C0%7C0%7C63 8081892123929669%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzI iLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000%7C%7C%7C&sdata=etYqO01OszhEpqgjLeKQTM C9b3wT0sc%2FcN8oJo9eEhk%3D&reserved=0



    ------------------------------

    Message: 8
    Date: Sun, 1 Jan 2023 14:23:13 +1100
    From: Chris Angelico <rosuav@gmail.com>
    To: python-list@python.org
    Subject: Re: NoneType List
    Message-ID:
    <CAPTjJmq=n0=B7fHvtydTwe0eZ+GVxTzGH-3TJDX6E9PyVHsEnQ@mail.gmail.com> Content-Type: text/plain; charset="UTF-8"

    On Sun, 1 Jan 2023 at 14:19, <avi.e.gross@gmail.com> wrote:
    Had a language like that been created today, I wonder if some designs
    might have looked a bit different so that some functions could be
    called with optional arguments that specified what the user wanted
    returned.

    Frankly, I doubt it. While you can argue "returning self is more useful" vs "returning None is more clear if you get it wrong", having options does NOT improve things, and just makes everything more complicated, slower, harder
    to comprehend, and generally worse to work with.

    A language should have some sort of consistent behaviour and stick to it. If that's not possible, an object type should at least have that.

    ChrisA


    ------------------------------

    Message: 9
    Date: Sat, 31 Dec 2022 23:16:10 -0500
    From: <avi.e.gross@gmail.com>
    To: "'Chris Angelico'" <rosuav@gmail.com>, <python-list@python.org> Subject: RE: NoneType List
    Message-ID: <00fd01d91d97$c78994d0$569cbe70$@gmail.com>
    Content-Type: text/plain; charset="us-ascii"

    Chris,

    There is much to say about consistent behavior as compared to flexibility
    and convenience.

    I have seen other languages provide functions for example, where the result can vary and often cause confusion. R had a function that would sometimes notice the result could be simplified and return that. Guess what? It caused lots of problems and an option was added that said it should NOT simplify
    and always return the same kind of thing.

    Consider what happens if a calculation that returned a matrix would decide
    that is there was only one columns, it would return a vector/array/whatever
    as a one-dimensional result and if the calculation produced a 1 by 1 matrix,
    it would simply return a scalar value!

    But it may be a feature you want in some cases, albeit rarely when the
    results of the function are fed into something that is not expecting it. Various forms of polymorphism can be helpful but can also be very confusing.

    Some solutions are what I have described in earlier messages and some
    languages blur distinctions. Again, in R, there may not be a scalar as all
    you have is a vector of length one. But matrices even of 1-D are not vectors and I have had to interconvert between them to make some code run.

    I am not making comparisons in the sense that nothing other languages choose
    to do is binding on what Python should do. Still, I think it is wrong to suggest that it does not often do partially ambiguous things from some perspective. Many functions will take a variety of arguments and return something reasonable but different each time.

    As a dumb example, what does a simple function like max() return if fed just integers, just floating point or a combination of both? It seems to return whatever type the maximum indicates. But it also accepts characters and
    sorts them appropriately returning type 'str' and probably accepts and
    returns all kinds of objects if you specify a key function.

    Is that so much different than we are discussing in that there isn't any absolute consistency and things can go various ways in terms of return
    value? Heck, I can even make max() return None!


    -----Original Message-----
    From: Python-list <python-list-bounces+avi.e.gross=gmail.com@python.org> On Behalf Of Chris Angelico
    Sent: Saturday, December 31, 2022 10:23 PM
    To: python-list@python.org
    Subject: Re: NoneType List

    On Sun, 1 Jan 2023 at 14:19, <avi.e.gross@gmail.com> wrote:
    Had a language like that been created today, I wonder if some designs
    might have looked a bit different so that some functions could be
    called with optional arguments that specified what the user wanted
    returned.

    Frankly, I doubt it. While you can argue "returning self is more useful" vs "returning None is more clear if you get it wrong", having options does NOT improve things, and just makes everything more complicated, slower, harder
    to comprehend, and generally worse to work with.

    A language should have some sort of consistent behaviour and stick to it. If that's not possible, an object type should at least have that.

    ChrisA
    --
    https://nam10.safelinks.protection.outlook.com/?url=https%3A%2F%2Fmail.pytho n.org%2Fmailman%2Flistinfo%2Fpython-list&data=05%7C01%7Cdvl%40psu.edu%7C744c 83fc485a4b1c79db08daec19a436%7C7cf48d453ddb4389a9c1c115526eb52e%7C0%7C0%7C63 8081892123929669%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzI iLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000%7C%7C%7C&sdata=etYqO01OszhEpqgjLeKQTM C9b3wT0sc%2FcN8oJo9eEhk%3D&reserved=0



    ------------------------------

    Message: 10
    Date: Sun, 1 Jan 2023 15:23:59 +1100
    From: Chris Angelico <rosuav@gmail.com>
    To: python-list@python.org
    Subject: Re: NoneType List
    Message-ID:
    <CAPTjJmqqGLqE=FepRMM1P95E3eGv5Qnq_=BfsGJNXuucLH6wMg@mail.gmail.com> Content-Type: text/plain; charset="UTF-8"

    On Sun, 1 Jan 2023 at 15:16, <avi.e.gross@gmail.com> wrote:

    Chris,

    There is much to say about consistent behavior as compared to
    flexibility and convenience.

    I have seen other languages provide functions for example, where the
    result can vary and often cause confusion. R had a function that would sometimes notice the result could be simplified and return that. Guess
    what? It caused lots of problems and an option was added that said it
    should NOT simplify and always return the same kind of thing.

    The option was presumably added because backward compatibility is important, but it would have been better to not need the option in the first place.

    As a dumb example, what does a simple function like max() return if
    fed just integers, just floating point or a combination of both? It
    seems to return whatever type the maximum indicates. But it also
    accepts characters and sorts them appropriately returning type 'str'
    and probably accepts and returns all kinds of objects if you specify a
    key function.

    Is that so much different than we are discussing in that there isn't
    any absolute consistency and things can go various ways in terms of
    return value? Heck, I can even make max() return None!


    ... yes? So? It still always returns the largest item in the list, for some definition of "largest". You'll never have that value returned wrapped up in
    a single-element list, though.

    ChrisA


    ------------------------------

    Message: 11
    Date: Sun, 1 Jan 2023 08:11:02 -0500
    From: Thomas Passin <list1@tompassin.net>
    To: python-list@python.org
    Subject: Re: NoneType List
    Message-ID: <71caabcd-65a0-8b3f-a971-79cd3f4415e1@tompassin.net>
    Content-Type: text/plain; charset=UTF-8; format=flowed

    On 12/31/2022 10:17 PM, avi.e.gross@gmail.com wrote:
    Agreed, there are lots of pro/con arguments and the feature is what it
    is historically and not trivial to change. Inline changes to an object
    make sense to just be done "silently" and if there are errors, they
    propagate the usual way.

    As Guido was a major influence at that time, one view was seen as
    more important and prevailed.

    Had a language like that been created today, I wonder if some designs
    might have looked a bit different so that some functions could be
    called with optional arguments that specified what the user wanted
    returned.

    Guido had been working on the ABC language for some years before he
    developed Python. ABC was intended mainly as a teaching and prototyping language. Guido probably had a good sense of what things worked well and
    what didn't in that usage. IIRC, Python did not originally have classes or instances, and a "fluent" style of programming probably wasn't in use yet. Having an object return itself after an operation is useful (mostly,
    perhaps) for fluent programming (that is, the style where one can write X.method1().method2().method3() ...).

    In particular, besides a function where you add a value returning nothing/None, there may be room for other choices and any choice
    hard-wired in would eleicit complaints from others.

    lst.add("Value")

    could also return one of several other things such as a pointer to the upgraded object but also of a pointer to the object as it looked
    before the change (not a serious proposal) or a True/False value
    specifying if the change was able to be completed (such as running out
    of memory, or the addition not being something you can put in the
    object) or even return what was added or how many objects are now in
    the object at the top level, or how many times the method was called so
    far!

    I suspect, at the expense of some overhead, you could just add an
    argument to many kinds of methods or even functions such as returning='option' that guides what you want returned, with the
    default often being what Guido and others currently have set.

    Python already allows functions to return anything they feel like, so
    this probably would not break many things.


    [continued in next message]

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