Greetings list, Using 3.7, in json module of the std lib there is json.load and json.loads . I gather json.loads is more used to convert string to dict structure. json.load might cause (it already causes) confusions. Suggestion: Rename json.load() so as not to confuse with json.loads() ^^_ Yours, Abdur-Rahmaan Janhangeer pythonmembers.club <http://www.pythonmembers.club/> | github <https://github.com/Abdur-rahmaanJ> Mauritius
On 11/27/2019 3:24 PM, Abdur-Rahmaan Janhangeer wrote:
Greetings list,
Using 3.7, in json module of the std lib there is json.load and json.loads . I gather json.loads is more used to convert string to dict structure. json.load might cause (it already causes) confusions.
Suggestion: Rename json.load() so as not to confuse with json.loads()
You'd either have to breaking existing code, or having 2 identical functions with different names. In either case, the churn and confusion would not be worth it. Eric
Those functions, ``load`` and ``loads``, for better or worse, are a standard across many modules. Now that the standard has been established, it's good to stick with it. Good interface design needs to consider familiarity as well as what might be best without any history. On Wed, Nov 27, 2019 at 12:24 PM Abdur-Rahmaan Janhangeer < arj.python@gmail.com> wrote:
Greetings list,
Using 3.7, in json module of the std lib there is json.load and json.loads . I gather json.loads is more used to convert string to dict structure. json.load might cause (it already causes) confusions.
Suggestion: Rename json.load() so as not to confuse with json.loads()
^^_ Yours,
Abdur-Rahmaan Janhangeer pythonmembers.club <http://www.pythonmembers.club/> | github <https://github.com/Abdur-rahmaanJ> Mauritius _______________________________________________ Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-leave@python.org https://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/EJTIVQ... Code of Conduct: http://python.org/psf/codeofconduct/
On Nov 27, 2019, at 12:27, Abdur-Rahmaan Janhangeer <arj.python@gmail.com> wrote:
Using 3.7, in json module of the std lib there is json.load and json.loads . I gather json.loads is more used to convert string to dict structure.
Yes, loads is to load from a string; load is used to load from a file (or file-like object).
json.load might cause (it already causes) confusions.
I’m curious what names you would use? Maybe load_string and load_file? Anyway, more explicit names might have been better, but load/loads is so well established—across other document types, and third-party modules as well as stdlib, and so on—that changing it in just one module would cause a lot more confusion than it could possibly solve, and changing it everywhere isn’t feasible. Plus, there’s decades worth of working code using these names; breaking all that code requires a really big benefit. Also, I think the other two quasi-standards out there for similar cases are much worse. Some modules have a single function that type-switches on string as contents vs. file, while others have a function that type-switches on string as pathname vs. file plus a separate fromstring function for parsing contents. That’s a lot more confusing. I frequently accidentally try to parse a pathname as an XML document, or to open a file using an XML document as a pathname, but I never make that mistake with JSON.
An IDE with support for PEP 484 / mypy / type annotations (and/or writing tests) can help minimize typing-related errors. https://github.com/python/typeshed/blob/master/stdlib/3/json/__init__.pyi https://github.com/python/mypy/blob/master/README.md#ide-linter-integrations... On Wednesday, November 27, 2019, Eric V. Smith <eric@trueblade.com> wrote:
On 11/27/2019 3:24 PM, Abdur-Rahmaan Janhangeer wrote:
Greetings list,
Using 3.7, in json module of the std lib there is json.load and json.loads . I gather json.loads is more used to convert string to dict structure. json.load might cause (it already causes) confusions.
Suggestion: Rename json.load() so as not to confuse with json.loads()
You'd either have to breaking existing code, or having 2 identical functions with different names. In either case, the churn and confusion would not be worth it.
Eric
_______________________________________________ Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-leave@python.org https://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/INEF3F... Code of Conduct: http://python.org/psf/codeofconduct/
Side q: Is there yet a way to get ? and/or ?? In IPython/Jupyter to list {typeshed,} annotations? On Thursday, November 28, 2019, Wes Turner <wes.turner@gmail.com> wrote:
An IDE with support for PEP 484 / mypy / type annotations (and/or writing tests) can help minimize typing-related errors.
https://github.com/python/typeshed/blob/master/stdlib/3/json/__init__.pyi
https://github.com/python/mypy/blob/master/README.md#ide-linter-integrations...
On Wednesday, November 27, 2019, Eric V. Smith <eric@trueblade.com> wrote:
On 11/27/2019 3:24 PM, Abdur-Rahmaan Janhangeer wrote:
Greetings list,
Using 3.7, in json module of the std lib there is json.load and
json.loads . I gather json.loads is more used to convert string to dict structure. json.load might cause (it already causes) confusions.
Suggestion: Rename json.load() so as not to confuse with json.loads()
You'd either have to breaking existing code, or having 2 identical functions with different names. In either case, the churn and confusion would not be worth it.
Eric
_______________________________________________ Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-leave@python.org https://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/INEF3F... Code of Conduct: http://python.org/psf/codeofconduct/
It's about ambiguity. Maybe loads is short for load string which in english is also a verb. Abdur-Rahmaan Janhangeer http://www.pythonmembers.club | https://github.com/Abdur-rahmaanJ Mauritius On Thu, 28 Nov 2019, 12:38 Wes Turner, <wes.turner@gmail.com> wrote:
An IDE with support for PEP 484 / mypy / type annotations (and/or writing tests) can help minimize typing-related errors.
https://github.com/python/typeshed/blob/master/stdlib/3/json/__init__.pyi
https://github.com/python/mypy/blob/master/README.md#ide-linter-integrations...
On Wednesday, November 27, 2019, Eric V. Smith <eric@trueblade.com> wrote:
On 11/27/2019 3:24 PM, Abdur-Rahmaan Janhangeer wrote:
Greetings list,
Using 3.7, in json module of the std lib there is json.load and json.loads . I gather json.loads is more used to convert string to dict structure. json.load might cause (it already causes) confusions.
Suggestion: Rename json.load() so as not to confuse with json.loads()
You'd either have to breaking existing code, or having 2 identical functions with different names. In either case, the churn and confusion would not be worth it.
Eric
_______________________________________________ Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-leave@python.org https://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/INEF3F... Code of Conduct: http://python.org/psf/codeofconduct/ _______________________________________________ Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-leave@python.org https://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/B6NRPA... Code of Conduct: http://python.org/psf/codeofconduct/
On Thu, Nov 28, 2019 at 02:06:08PM +0400, Abdur-Rahmaan Janhangeer wrote:
It's about ambiguity. Maybe loads is short for load string which in english is also a verb.
True. It took me a long time to stop getting confused between pickle.load and .loads until I stopped reading it as "loads" and started reading it as "load-s(tring)". I agree with you that this is a sub-optimal naming convention, and we would have been better if a different choice was made at the beginning. But unfortunately it is a widely used naming convention: * pickle * marshall * json * yaml (I think) * and probably more and not just in Python. But I agree with the others that the pain and disruption from changing it is greater than the benefit. We all just have to memorise that "loads" means "load-string" and not the present tense of load. -- Steven
For the future, at least I happen to be teaching essential std lib modules this week, i had a headache with how naming goes on (i was looking at how a beginner would learn). Poor me, what could be an intuitive learning journey has some clogs down the road. Abdur-Rahmaan Janhangeer http://www.pythonmembers.club | https://github.com/Abdur-rahmaanJ Mauritius On Thu, 28 Nov 2019, 14:57 Steven D'Aprano, <steve@pearwood.info> wrote:
On Thu, Nov 28, 2019 at 02:06:08PM +0400, Abdur-Rahmaan Janhangeer wrote:
It's about ambiguity. Maybe loads is short for load string which in english is also a verb.
True. It took me a long time to stop getting confused between pickle.load and .loads until I stopped reading it as "loads" and started reading it as "load-s(tring)".
I agree with you that this is a sub-optimal naming convention, and we would have been better if a different choice was made at the beginning. But unfortunately it is a widely used naming convention:
* pickle * marshall * json * yaml (I think) * and probably more
and not just in Python. But I agree with the others that the pain and disruption from changing it is greater than the benefit. We all just have to memorise that "loads" means "load-string" and not the present tense of load.
-- Steven _______________________________________________ Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-leave@python.org https://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/FVP522... Code of Conduct: http://python.org/psf/codeofconduct/
I happen to be teaching essential std lib modules this week, i had a headache with how naming goes on (i was looking at how a beginner would learn). Poor me, what could be an intuitive learning journey has some clogs down the road.
To some degree, that's an inevitable part of the learning process. The most we can realistically do is try to be aware of it during design, but I suspect there's always going to be some "more intuitive" way we could have done it when looking back with hindsight. On Thu, Nov 28, 2019 at 6:04 AM Abdur-Rahmaan Janhangeer < arj.python@gmail.com> wrote:
For the future, at least
I happen to be teaching essential std lib modules this week, i had a headache with how naming goes on (i was looking at how a beginner would learn). Poor me, what could be an intuitive learning journey has some clogs down the road.
Abdur-Rahmaan Janhangeer http://www.pythonmembers.club | https://github.com/Abdur-rahmaanJ Mauritius
On Thu, 28 Nov 2019, 14:57 Steven D'Aprano, <steve@pearwood.info> wrote:
On Thu, Nov 28, 2019 at 02:06:08PM +0400, Abdur-Rahmaan Janhangeer wrote:
It's about ambiguity. Maybe loads is short for load string which in english is also a verb.
True. It took me a long time to stop getting confused between pickle.load and .loads until I stopped reading it as "loads" and started reading it as "load-s(tring)".
I agree with you that this is a sub-optimal naming convention, and we would have been better if a different choice was made at the beginning. But unfortunately it is a widely used naming convention:
* pickle * marshall * json * yaml (I think) * and probably more
and not just in Python. But I agree with the others that the pain and disruption from changing it is greater than the benefit. We all just have to memorise that "loads" means "load-string" and not the present tense of load.
-- Steven _______________________________________________ Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-leave@python.org https://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/FVP522... Code of Conduct: http://python.org/psf/codeofconduct/
_______________________________________________ Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-leave@python.org https://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/7ATKEJ... Code of Conduct: http://python.org/psf/codeofconduct/
"Designed With Learning in Mind" Abdur-Rahmaan Janhangeer http://www.pythonmembers.club | https://github.com/Abdur-rahmaanJ Mauritius
Maybe methods for learning to search the code and docs (rather than memorizing APIs) would be a worthwhile exercise? # Python import json help(json) # IPython !pydoc json import json json? json?? # RTD: Read The Docs (and/or update the docs) https://docs.python.org/3/search.html?q=loads https://docs.python.org/3/library/json.html#basic-usage https://github.com/python/cpython/blob/master/Doc/library/json.rst # RTS: Read The Source https://duckduckgo.com/?q=github+cpython+json https://github.com/python/cpython/blob/master/Lib/json/__init__.py#L299 https://github.com/python/cpython/tree/master/Lib/test/test_json On Thursday, November 28, 2019, Abdur-Rahmaan Janhangeer < arj.python@gmail.com> wrote:
"Designed With Learning in Mind"
Abdur-Rahmaan Janhangeer http://www.pythonmembers.club | https://github.com/Abdur-rahmaanJ Mauritius
I'd be +1 on adding a better named alias for loading strings to all of these libraries. Seems to me like it is a pretty awful naming convention even if it is standard across the profession, and that adding load_string or load_str as an alias for loads would be a Very Good Thing (TM) with few downsides. Two points in favor: 1. It is an obfuscated naming convention. 2. The presence of the loads() naming convention encourages people new to coding to do the exactly wrong thing and use MORE obfuscated names for their own methods and not less. In fact I took a cue from the standard library and added a loads() method to my own specialized file reader (for a soil FEA program) and regretted it later. I learned from my mistake that descriptive names are superior, and also that naming is hard, and thankfully it was relatively painless for me to change it. Actually this issue has still been confusing for me sometimes even years after first using the API, since I haven't used these libraries often and tend not to remember it when I come back to them (this conversation will likely make it stick in my memory better). I even think it would be preferable for the loads() documentation to say that it is an alias for load_str(), and not the other way around. On Thu, Nov 28, 2019, 7:37 AM Wes Turner <wes.turner@gmail.com> wrote:
Maybe methods for learning to search the code and docs (rather than memorizing APIs) would be a worthwhile exercise?
# Python import json help(json)
# IPython !pydoc json import json json? json??
# RTD: Read The Docs (and/or update the docs) https://docs.python.org/3/search.html?q=loads
https://docs.python.org/3/library/json.html#basic-usage
https://github.com/python/cpython/blob/master/Doc/library/json.rst
# RTS: Read The Source https://duckduckgo.com/?q=github+cpython+json
https://github.com/python/cpython/blob/master/Lib/json/__init__.py#L299
https://github.com/python/cpython/tree/master/Lib/test/test_json
On Thursday, November 28, 2019, Abdur-Rahmaan Janhangeer < arj.python@gmail.com> wrote:
"Designed With Learning in Mind"
Abdur-Rahmaan Janhangeer http://www.pythonmembers.club | https://github.com/Abdur-rahmaanJ Mauritius _______________________________________________ Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-leave@python.org https://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/YGP2BI... Code of Conduct: http://python.org/psf/codeofconduct/
Abdur-Rahmaan Janhangeer writes:
"Designed With Learning in Mind"
That's Python. Guido said so from the beginning, and in modern Python development we tend to favor full words with a consistent convention for separating them in multiword identifiers and so on. Syntax additions get fully bikeshedded; "tend to favor" is not acceptable there! Python is also developed mainly by volunteers, with a relatively conservative attitude toward additions to the stdlib. Some packages do get developed here on Python Ideas and Python Dev, and fast-tracked because their proponents are well-respected. Those tend to get quite a lot of attention to nomenclature ("bikeshedding", as it's called). But most aren't (and that includes most by famous proponents, too![1]) That means that some volunteer typically spends years polishing up their package to *their* satisfaction, and by the time it gets added it has a substantial following and a substantial installed base (if it didn't, it likely wouldn't get added), making backward compatibility a thing. At that point adding synonyms may backfire. People using synonyms run into trouble, they ask on StackExchange, and the grizzled old folks (who constitute a large fraction of the People Who Answer) will go "WTF is this?" and move on to a question they can answer off the top of their heads. You don't have to like it. I don't think anybody likes suboptimal naming, they just like it better than they like backward-incompatible renames or namespace pollution. You can't really expect others to be happy with wholesale changes to the environment, even if they're fully backward compatible as the proposals to add aliases for json.loads and calendar.calendar are. (As usual, you can say "I just want these two," and we'll respond "OK, but the community as a whole will want a million of them, we all have our favorites, and if we accept yours, how do we deny theirs?") You can always just write wrapper modules that do nothing but rename any identifiers you think are unintuitive. It would be interesting to see how much uptake you get from new users. (I exclude existing users because, however much they *like* your names, they are likely to be biased against the changes by backward compatibility with their own code and with third-party code -- not really a fair test. Although if you get a lot of uptake there it would be a strong recommendation.) Footnotes: [1] For example, consider the dates of implementation of PEPs 3107 and 484. 3107 wasn't written by Guido, but he wanted and advocated it, and AIUI he always intended it to support something like 484.
On Nov 28, 2019, at 06:31, Ricky Teachey <ricky@teachey.org> wrote:
I'd be +1 on adding a better named alias for loading strings to all of these libraries.
Including the ones that aren’t in the stdlib? If so, how do we do that? If not, won’t it be even more confusing for people who learn json.load_string when they go to use PyYAML and there’s no yaml.load_string? Sure, they’ll complain to the PyYAML devs, and eventually, most of the most common libraries will catch up, but you’re talking about a few years of extra confusion before you get the long-term benefits. Also, all the existing code, tutorials, StackOverflow answers, etc. that uses loads will still be using loads, so most people are going to have to learn what it means anyway. People are still getting confused over find_all vs. findall and writing StackOverflow questions asking why some module is giving them a NameError when they try to use findall a decade later. And the same is true for some of the pep8-naming changes that came with 3.0; you can still find StackOverflow questions where the accepted answer on the canonical dup question says to use threading.currentThread even though current_thread was added, and currentThread turned into a compatibility alias, back in 2.6. So the Very Good Thing isn’t actually as good as you’d hope—people will still have to learn loads—and the downsides are bigger than they appear at first—it will be a years-long process to get the entire Python ecosystem consistent on a new naming convention. That doesn’t mean it definitely isn’t worth doing, but it does mean you need to argue that it’s compelling enough to be worth the tradeoff anyway, rather than ignoring the cost and arguing as if we had a time machine and could go back to whenever pickle was added and change history to avoid all the downsides. As a side note: I found it much more confusing when I learned pickle that the opposite of load was not store, but dump. To me, dump sounds like a debugging function that would format a pickle with all relevant details and print it to stderr (much like dis), not a function you’d use to convert an object to a pickle and save in a file.
On Fri, Nov 29, 2019 at 12:55:13AM +0900, Stephen J. Turnbull wrote:
Abdur-Rahmaan Janhangeer writes:
"Designed With Learning in Mind"
That's Python. Guido said so from the beginning,
Is it? Did he? Do you have references for that? https://duckduckgo.com/?q=python+%22Designed+With+Learning+in+Mind%22 I don't think that Python is "designed with learning in mind". Python is not Scratch, nor is it ABC. ABC was a *big* influence on the evolution of Python, but (in my opinion) at least half of that influence was to convince Guido *not* to make Python "designed with learning in mind". For example, ABC used its own alledgedly "beginner friendly" terminology that nobody else in programming used; Python mostly sticks to common terminology used by other languages which will be recognised by programmers coming from other languages. [...]
Footnotes: [1] For example, consider the dates of implementation of PEPs 3107 and 484. 3107 wasn't written by Guido, but he wanted and advocated it, and AIUI he always intended it to support something like 484.
Off-topic: I'm consistently and frequently frustrated by the community's use of PEP id numbers as jargon. I consider it to be a classic example of the use of jargon to exclude, rather than the sense of using it to streamline communication. They're like the old joke about the members of a club who have collected all their old jokes and funny anecdotes into a numbered list, so one need only announce "5379" and the club members will burst out into laughter. Great for those who have memorised the list, and perplexing and exclusionary to everyone else. They're worse than three- and four-letter acronyms, because at least acronyms have some connection to the English phrase (usually the initial letters) and you can often work out the meaning in context; but PEPs are arbitrary identifiers. Unless you have memorised the mapping from PEP ids to descriptions, there is nothing to link the id to the meaning. Apart from PEP 8, I don't know a single PEP id off by heart (not even the PEPs I have authored) and your footnote above reads as pure gobbledygook to me. There is not enough context to guess the meaning of 3107 or 484 (Guido intended 3107 to support 484 did he? how uninformative) so there is nothing to be done except to stop reading, switch to a browser, and google them both. And there are so many PEPs, most of which are of interest only to a tiny subset of the Python community, or old and obscure, that (apart from PEP 8) most of us don't even get the chance to memorise them through repetition. If I casually mentioned 317 into a conversation, how many people would know it was about prohibiting implicit exception instantiation? Here endeth the rant. -- Steven
On Fri, Nov 29, 2019 at 7:59 AM Steven D'Aprano <steve@pearwood.info> wrote:
Off-topic:
I'm consistently and frequently frustrated by the community's use of PEP id numbers as jargon. I consider it to be a classic example of the use of jargon to exclude, rather than the sense of using it to streamline communication.
You're fighting something way WAY larger than Python, namely the use of technical spec references to represent what they're talking about. Off the top of my head: * Wireless speeds described as G, N, AC, etc, eg advertising a "Wireless AC" router * Advertising internet connection features such as "Annex M" * Defining file/message formats by RFCs (even superseded ones) * Citing XKCD numbers, most notably 936 but also others * Demanding your rights under the Nth Amendment (of the US Constitution but nobody ever even says that part) * Describing a type of scam by the section of Nigerian law that makes it illegal Yes, the numbers don't mean anything on their own. But they are VERY easy to look up (mostly - sometimes you need to know the context, like that wireless standards are all "802.11<letter>"), so they *do* streamline communication. In some contexts, using one of these kinds of references automatically creates a hyperlink to the document itself. That does help to make the jargon more accessible. I don't know if it's possible/practical to do that on mailing lists, though. ChrisA
On 2019-11-28 20:51, Steven D'Aprano wrote: [snip]
I'm consistently and frequently frustrated by the community's use of PEP id numbers as jargon. I consider it to be a classic example of the use of jargon to exclude, rather than the sense of using it to streamline communication.
[snip]
Apart from PEP 8, I don't know a single PEP id off by heart (not even the PEPs I have authored) and your footnote above reads as pure gobbledygook to me. There is not enough context to guess the meaning of 3107 or 484 (Guido intended 3107 to support 484 did he? how uninformative) so there is nothing to be done except to stop reading, switch to a browser, and google them both.
And there are so many PEPs, most of which are of interest only to a tiny subset of the Python community, or old and obscure, that (apart from PEP 8) most of us don't even get the chance to memorise them through repetition. If I casually mentioned 317 into a conversation, how many people would know it was about prohibiting implicit exception instantiation?
Well, there's PEP 0, which is the index. Oh, and PEP 404. :-) The only other one I can remember is PEP 393 (Flexible String Representation), and that's because of writing an extension.
I'd be +1 on adding a better named alias for loading strings to all of these libraries.
Including the ones that aren’t in the stdlib? If so, how do we do that?
Leading by example of not sticking forever with obfuscated naming. So the Very Good Thing isn’t actually as good... you need to argue that
it’s compelling enough to be worth the tradeoff anyway, rather than ignoring the cost and arguing as if we had a time machine
I ignored them because none of those issues seem like a big deal to me. But I'm also mindful I've been at this much much less time than most of you. So I'm still +1. Just add the better named function as an option and be done with it; other than adding it to the docs, leave everything else as it is. New people will start using it (because it is so much more obvious what it is) and their understanding, and the new code they write mimicking the standard library, will be improved. And later other libraries will follow the lead that better names for things are very very important. Obfuscated names have a huge tendency to push people away. As a side note: I found it much more confusing when I learned pickle that
the opposite of load was not store, but dump. To me, dump sounds like a debugging function that would format a pickle with all relevant details and print it to stderr (much like dis), not a function you’d use to convert an object to a pickle and save in a file.
That would be an example of a name that might be unintuitive (I think of a dump truck and intuit it right away, but to each his own). It isn't an OBFUSCATED name. No one sees that example as a signal that it's a good idea to do objectively bad naming, like loads() does. But someone sees loads() and thinks, "ah, short names are really good", and go with prof() rather than process_file(). So here I'm really talking about what I'm calling obfuscated names, not necessarily names that aren't as intuitive as they could be.
Ricky Teachey writes:
Leading by example of not sticking forever with obfuscated naming.
We do push back against obfuscated naming, including abbreviations like loads, but forward-looking, not backward-looking. There's also the problem in the stdlib that often a requirement for a module to be added is that it have a large following. In those cases the author may or may not have followed what we consider good naming practices, but they were good enough for the users.
So I'm still +1. Just add the better named function as an option and be done with it; other than adding it to the docs, leave everything else as it is.
I would find this very annoying, because I believe it would lead to widespread namespace pollution. I use dir() a lot to remind myself of APIs, and aliases that would confuse me and slow reading (I'm old enough to have vision issues) would anger me. Using dir() works for me because I read docs before I start typing code (hentai, I know), and have a relatively good memory after one or two readings. I don't know how many people have those characteristics, though. There's second aspect of namespace pollution, which is that users will frequently use plausible alternatives for their own value-added APIs. I don't know if this actually causes confusion, though.
No one sees that example as a signal that it's a good idea to do objectively bad naming, like loads() does. But someone sees loads() and thinks, "ah, short names are really good", and go with prof() rather than process_file().
People who think short names are good are more worried about typing them than anything else in my experience. They're not imitating anybody, they're optimizing the code in front of them.
So here I'm really talking about what I'm calling obfuscated names, not necessarily names that aren't as intuitive as they could be.
One person's unintuitive can easily be another's obfuscated. pickle.dump() is *obfuscated* to anybody old enough to have used "set limit core unlimited" (even if they were born in 2010). For those of us old enough to remember "can't eat just one", "memory dump" (of which "core dump" is a special case) is an extremely strong association. I'm basically -1 on any aliasing. I think there's way too many that have been proposed. I can't see a way limit them that doesn't read "screw you" to the proposals that are denied, and it would be a burden on me, it would cause confusion, and I don't think the benefits are likely to be great. Those are all subjective priors, so I could be moved if some proponent is willing to go through the last five years of Python List, Python Ideas, Python Dev, and the tracker and provide a list of aliasing and renaming proposals, and show that the likely level of namespace pollution is low.
Steven D'Aprano writes:
On Fri, Nov 29, 2019 at 12:55:13AM +0900, Stephen J. Turnbull wrote:
Abdur-Rahmaan Janhangeer writes:
"Designed With Learning in Mind"
That's Python. Guido said so from the beginning,
Is it? Did he? Do you have references for that?
Yes, it is in my opinion (I use it in teaching all the time in the same way I would use pseudo-code, and I haven't taught a class in programming in 25 years). Yes, he did. No, just my memory of occasions where he has said or posted that use of Python as a teaching language informed his design philosophy and decisions (which is the minimum that "with learning in mind" implies).
Python is not Scratch, nor is it ABC. ABC was a *big* influence on the evolution of Python, but (in my opinion) at least half of that influence was to convince Guido *not* to make Python "designed with learning in mind".
"Design with learning in mind" literally means "don't forget about beginners in Python and in programming", not "sacrifice everything else on the altar of education".
For example, ABC used its own alledgedly "beginner friendly" terminology that nobody else in programming used; Python mostly sticks to common terminology used by other languages which will be recognised by programmers coming from other languages.
Which is a decision that has learning Python (vs. learning programming in general) in mind, no?
Off-topic:
I'm consistently and frequently frustrated by the community's use of PEP id numbers as jargon. I consider it to be a classic example of the use of jargon to exclude, rather than the sense of using it to streamline communication.
Jargon has a third role: to identify members of the community. Of course that overlaps with exclusion, but it's not the same. And PEP numbers have a fourth purpose when used as jargon (this applies to any numbered formal standard such as RFCs or ISO): they are self-citing. In that sense, they are *inclusive*. They're an invitation to learn more than you ever wanted to know about the things the community cares about.
Apart from PEP 8, I don't know a single PEP id off by heart (not even the PEPs I have authored)
I know more that that (off the top of my head, 0, 1, 7, 8, 263, 383, 393, 484, and 3000, none of which I authored although I was extremely noisy about 263), which is less than 2% I guess. But when I type "pep" into my browser's address bar, I get "https://www.python.org/dev/peps/pep-0000/" as the top choice. I then substitute the PEP number for "0000" and voilà! Self-citing. Most people will have to work a little harder at first, but if they do it a few times they will be rewarded with a well-trained browser.
and your footnote above reads as pure gobbledygook to me.
That's what footnotes are for: to hold gobbledygook that only the initiated or directly concerned will care about. I put it there so readers could ignore it if they wanted to without interrupting the flow. Little did I know it would trigger a rant.
There is not enough context to guess the meaning of 3107 or 484 (Guido intended 3107 to support 484 did he? how uninformative) so there is nothing to be done except to stop reading, switch to a browser, and google them both.
Which was my intention, because I wanted readers to be able to easily confirm the metadata (specifically, dates). Self-citing. Steve
Education is one side of it. It's about intuitive API Abdur-Rahmaan Janhangeer http://www.pythonmembers.club | https://github.com/Abdur-rahmaanJ Mauritius
And PEP numbers have a fourth purpose when used as jargon (this applies to any numbered formal standard such as RFCs or ISO): they are self-citing. In that sense, they are *inclusive*. They're an invitation to learn more than you ever wanted to know about the things the community cares about.
using the PEP
Apart from PEP 8, I don't know a single PEP id off by heart (not even the PEPs I have authored)
I know more that that (off the top of my head, 0, 1, 7, 8, 263, 383, 393, 484, and 3000, none of which I authored although I was extremely noisy about 263), which is less than 2% I guess.
I think some people simply remember numbers more than others -- I, for one, an NOT a number rememberer -- PEP8 is the only one I know off hand, including the one I wrote. which isn't to say the numbers aren't useful, just that it would be SO much more communicative to use the number (for easy look up) AND a brief description or title. Frankly, I get confused when there are discussion on this list (or python-dev, or) about currently PEPs in the midst of active discussion! Is is THAT hard to add a little text? And it's not just PEPs -- at work, I have to read a LOT of emails about the development of our Annual Operating plan, and most folks talk about "goal 4" or "goal 2", and I have a hard time keeping them straight -- and there are only 6 goals! -CHB -- Christopher Barker, PhD Python Language Consulting - Teaching - Scientific Software Development - Desktop GUI and Web Development - wxPython, numpy, scipy, Cython
On Thu, Nov 28, 2019 at 06:18:11PM -0500, Ricky Teachey wrote:
Leading by example of not sticking forever with obfuscated naming.
"loads" is not obfuscated naming. It has an easy-to-remember (if not totally obvious) meaning once you realise it is supposed to be pronounced as "load-s" (s for string) rather than "loads". json.xtagbe would be obfuscated naming. Or json._9263, or json.pencil. Python uses close-to natural language identifiers. And we need to learn how to correctly parse natural language identifiers: the os module is "o s", not "os sounds like aus or oz". "thread" is "th-red", not "th-read". English spelling is weird and inconsistent, with dozens or more of homonyms and homographs, like: project, bat, lie, fair, second, fine (homonyms) refuse, resume, minute (homographs) etc. "loads" is a homograph, as it can be read as loads (as in "he loads the dishwasher") or load-s (s for string). There may be languages with a perfectly rational and consistent relationship between written symbols and sounds, but I don't know of any. (And I'd expect that such a language would either have a very large number of symbols, or support only a very small fraction of the sounds that human speach can make.) For good or ill, if we want our code to look even a little bit like English, we're going to need to deal with the complexity of English spelling. Programming uses lots of initialisms, abbreviations and hybrid words, such as: os ram ssd dir json xml len chr EOF I/O rlcompleter pprint sqlite etc, and loads is not particularly worse than the rest.
So I'm still +1. Just add the better named function as an option and be done with it; other than adding it to the docs, leave everything else as it is. New people will start using it (because it is so much more obvious what it is) and their understanding, and the new code they write mimicking the standard library, will be improved. And later other libraries will follow the lead that better names for things are very very important.
I dispute that the alternative is a "better" name. Better for who? Better in what way? Forcing newbies to learn *two* names for the same method does not sound like an improvement to me. You say "leave everything else as it is", so newcomers will still see the old name in code, in tutorials, in blog posts, in books, on Stackoverflow answers, etc. So they still have to learn that "loads" is "load s(tring)". Effectively you are swapping one problem: "what's the difference between load and loads?" for two problems: "what's the difference between load and loads?" "what's the difference between loads and load_string?" -- Steven
One of them can maybe be deprectated json.load(<string here>) for file: json.load(file=<file obj>) Abdur-Rahmaan Janhangeer http://www.pythonmembers.club | https://github.com/Abdur-rahmaanJ Mauritius
On 29/11/2019 10:45, Abdur-Rahmaan Janhangeer wrote:
One of them can maybe be deprectated
json.load(<string here>)
for file:
json.load(file=<file obj>)
Ew ew ew ew ew! No thanks, I'd like my string parser to remain *clearly different* from my file parser. json.loads() is just fine, please don't mess with it. -- Rhodri James *-* Kynesim Ltd
On Fri, Nov 29, 2019 at 9:48 PM Abdur-Rahmaan Janhangeer <arj.python@gmail.com> wrote:
One of them can maybe be deprectated
json.load(<string here>)
for file:
json.load(file=<file obj>)
Deprecation is not a solution. You're still going to have stuff out there using the old name (Stack Overflow posts, blogs, articles, books, etc etc etc etc), and people *will* have to learn the meaning of both. Additionally, churn like this - renaming things for no reason other than "the new name is somehow better" - tends to create the sense that the language is constantly in flux, and that today's code is going to be broken tomorrow. Imagine a Stack Overflow answer that has to be edited to say "For Python versions up to 3.8, use json.loads; for versions 3.9 and up, use json.load_string", and then if it uses a couple of other APIs that have been renamed, it needs to multiply that out exponentially... no thanks. I get enough of that from React.js. -1 on renaming. -1 on deprecating. -1 on creating an unnecessary alias. ChrisA
Message to author of PEP 1437: _please read some threads like these_
-1 on renaming. -1 on deprecating. -1 on creating an unnecessary alias.
Maybe if the change's a breaking one, we might wait for a breaking event to sneak this one in. Knowing Python, maybe a stdlib intuitiveness workgroup will be set up. They'll work (hard) to make the std lib as candy as possible while candy-ing everyone onboard This week i have "cool 3rd party packages", a thread like this won't appear 🛫 Abdur-Rahmaan Janhangeer http://www.pythonmembers.club | https://github.com/Abdur-rahmaanJ Mauritius
For python it's: for 2 use this, for 3 that (now everyone's pretty smart to distinguish). Talking of react, i'm thankful enough for py's std lib. Each time i switch to Js, i wish the std lib was a tidbit more furnished. Abdur-Rahmaan Janhangeer http://www.pythonmembers.club | https://github.com/Abdur-rahmaanJ Mauritius
On 29/11/2019 13:36, Abdur-Rahmaan Janhangeer wrote:
= Chris Angelico -1 on renaming. -1 on deprecating. -1 on creating an unnecessary alias.
Maybe if the change's a breaking one, we might wait for a breaking event to sneak this one in.
Or we could accept that it is what it is. I'm with Chris: -1 on making life complicated. -- Rhodri James *-* Kynesim Ltd
On 11/29/19 7:21 AM, Chris Angelico wrote:
On Fri, Nov 29, 2019 at 9:48 PM Abdur-Rahmaan Janhangeer <arj.python@gmail.com> wrote:
One of them can maybe be deprectated
json.load(<string here>)
for file:
json.load(file=<file obj>)
Deprecation is not a solution. You're still going to have stuff out there using the old name (Stack Overflow posts, blogs, articles, books, etc etc etc etc), and people *will* have to learn the meaning of both. Additionally, churn like this - renaming things for no reason other than "the new name is somehow better" - tends to create the sense that the language is constantly in flux, and that today's code is going to be broken tomorrow. Imagine a Stack Overflow answer that has to be edited to say "For Python versions up to 3.8, use json.loads; for versions 3.9 and up, use json.load_string", and then if it uses a couple of other APIs that have been renamed, it needs to multiply that out exponentially... no thanks. I get enough of that from React.js.
-1 on renaming. -1 on deprecating. -1 on creating an unnecessary alias.
ChrisA
My personal feeling is that adding a significantly better name, and deprecating the old name (maybe never going past the state of documenting that it is deprecated and suggesting using the better name, one reason not to have an automatic removal of deprecated features) is viable if the name improvement is big enough. If we are going to use the existing web mentions, then Python would still be back as a 2.x version, and the language would be very static and 'old' That doesn't answer the question of if the new name is enough better to be worth it. One issue is that since Python allows the user to monkey-patch library code, ANY expansion of name space is potentially breaking, Python has almost no namespace reserved for the language designers that users are allowed to intrude on (maybe dunders are reserved enough, but we don't want to be using dunders as part of user accessed API). Which means that even if we deprecate loads, the standard library should continue to use it and not the new load_string for awhile until it is felt safe that few people are monkey patching in a load_string member, and we can break the code. -- Richard Damon
On Sat, Nov 30, 2019 at 1:33 AM Richard Damon <Richard@damon-family.org> wrote:
My personal feeling is that adding a significantly better name, and deprecating the old name (maybe never going past the state of documenting that it is deprecated and suggesting using the better name, one reason not to have an automatic removal of deprecated features) is viable if the name improvement is big enough.
Perhaps, IF the improvement is big enough. A marginal improvement is not worth all that hassle. And if you keep both names, you forever have people wondering what the difference is. As an example, Python's threading module has duplicate names eg "current_thread" and "currentThread". The depreferred names are documented up to and including Python 2.7, but they still exist in the latest 3.x.
If we are going to use the existing web mentions, then Python would still be back as a 2.x version, and the language would be very static and 'old'
This applies only to bare renames. If a completely new feature is added, it's not going to run into this problem; you have the normal thing of "requires Python 3.5+", but that doesn't get more complicated as you add more features - if you have one that was introduced in 3.5 and another that was introduced in 3.7, then you need 3.7, it's that simple. Much more complicated when some things come and go, so the correct thing to do will change multiple times.
That doesn't answer the question of if the new name is enough better to be worth it.
Agreed. I don't see that it is, in this instance.
One issue is that since Python allows the user to monkey-patch library code, ANY expansion of name space is potentially breaking, Python has almost no namespace reserved for the language designers that users are allowed to intrude on (maybe dunders are reserved enough, but we don't want to be using dunders as part of user accessed API). Which means that even if we deprecate loads, the standard library should continue to use it and not the new load_string for awhile until it is felt safe that few people are monkey patching in a load_string member, and we can break the code.
I don't think we need to worry about people poking arbitrary values into a stdlib module and breaking things. If someone's doing that and their code breaks in Python 3.10, that's on them. ChrisA
I don't think we need to worry about people poking arbitrary values
into a stdlib module and breaking things.
Agreed — and from years of participating in this community, I don’t think the danger of adding names to stdlib modules breaking people’s monkey-patched code has been a reason not to do it. -CHB If someone's doing that and
their code breaks in Python 3.10, that's on them.
ChrisA _______________________________________________ Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-leave@python.org https://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/4BNNN4... Code of Conduct: http://python.org/psf/codeofconduct/
-- Christopher Barker, PhD Python Language Consulting - Teaching - Scientific Software Development - Desktop GUI and Web Development - wxPython, numpy, scipy, Cython
On Fri, Nov 29, 2019 at 12:23:41PM +0900, Stephen J. Turnbull wrote:
Steven D'Aprano writes:
On Fri, Nov 29, 2019 at 12:55:13AM +0900, Stephen J. Turnbull wrote:
Abdur-Rahmaan Janhangeer writes:
"Designed With Learning in Mind"
That's Python. Guido said so from the beginning,
Is it? Did he? Do you have references for that?
Yes, it is in my opinion (I use it in teaching all the time in the same way I would use pseudo-code, and I haven't taught a class in programming in 25 years).
Yes, he did.
No, just my memory of occasions where he has said or posted that use of Python as a teaching language informed his design philosophy and decisions (which is the minimum that "with learning in mind" implies).
Guido might have something different to say about all this, but according to his blog, he *literally* designed Python as a scripting language for himself to glue together libraries written in C for the Amoeba operating system. "My original motivation for creating Python was the perceived need for a higher level language in the Amoeba project. ... So there was a need for a language that would “bridge the gap between C and the shell.” For a long time, this was Python’s main catchphrase." http://python-history.blogspot.com/2009/01/personal-history-part-1-cwi.html He describes his design of the language here: http://python-history.blogspot.com/2009/01/pythons-design-philosophy.html and notably missing from that list of design principles is anything about teaching programming or making it easier to learn or "Designed With Learning in Mind". In fact, some of the features of ABC that actually were designed with learning in mind were consciously rejected by Guido when designing Python. Honestly, this discussion is quite surreal. The json.load/loads API is clearly copied from the same API in the pickle and marshal modules, which are some of the oldest APIs in Python, going back to at least Python 1.5 if not older. So we have people simultaneously arguing that: * the load/loads distinction is hard to learn * and that Python was designed to be easy to learn from the earliest days which is contradictory. If it had been, the pickle/marshal API probably wouldn't have used loads and json wouldn't have copied it. Python naming conventions have evolved, and the oldest APIs are not "Designed With Learning In Mind".
Python is not Scratch, nor is it ABC. ABC was a *big* influence on the evolution of Python, but (in my opinion) at least half of that influence was to convince Guido *not* to make Python "designed with learning in mind".
"Design with learning in mind" literally means "don't forget about beginners in Python and in programming", not "sacrifice everything else on the altar of education".
That's not what it *literally* means. Its literal meaning is a lot closer to the second statement than the first, only without the perjorative elements of sacrificing to the cult of education. In any case, it is a matter of historical fact (to the degree that we believe Guido's account, and we have no reason to think that he is lying) that he didn't design Python with beginners in mind.
For example, ABC used its own alledgedly "beginner friendly" terminology that nobody else in programming used; Python mostly sticks to common terminology used by other languages which will be recognised by programmers coming from other languages.
Which is a decision that has learning Python (vs. learning programming in general) in mind, no?
No. If you want to learn programming concepts, you might prefer ABCs terminology. That at least was what the ABC designers thought; your mileage may vary. But ABC was designed with learning in mind: https://homepages.cwi.nl/~steven/abc/teaching.html just as Scratch and similar languages are. Using ABC for learning was the reason why it was created, and its design reflected that. This is not why Python was created, and while Guido copied some of the concepts from ABC, he consciously rejected others. One of those concepts he intentionally rejected was that the user had no prior experience and was learning how to program. -- Steven
On Fri, Nov 29, 2019 at 6:52 PM Steven D'Aprano <steve@pearwood.info> wrote:
No. If you want to learn programming concepts, you might prefer ABCs terminology. That at least was what the ABC designers thought; your mileage may vary. But ABC was designed with learning in mind:
That was clearly written some time ago :-) -- but when I read it now, I think you could replace "ABC" with "Python", and it would look a lot like many arguments written now for why Python is a good first programming language. And Guido did get involved quite some time ago (1999?) with the "CP4E" (Computer Programming for Everyone) idea. No, that was not right at the beginning, but it was pretty early compared to say, now. https://www.python.org/doc/essays/cp4e/ -CHB -- Christopher Barker, PhD Python Language Consulting - Teaching - Scientific Software Development - Desktop GUI and Web Development - wxPython, numpy, scipy, Cython
On Nov 29, 2019, at 02:42, Steven D'Aprano <steve@pearwood.info> wrote:
Programming uses lots of initialisms, abbreviations and hybrid words, such as:
os ram ssd dir json xml len chr EOF I/O rlcompleter pprint sqlite
etc, and loads is not particularly worse than the rest.
I agree with your sentiment; and I’m -1 on the change, but it’s worth pointing out that the amount of abbreviation and portmanteuing that’s considered appropriate has changed over the years. The names Guido gave things in 1991 aren’t necessarily the names he’d come up with today; if he were inventing `loads` 28 years later, I think he would have called it `load_string`. And, if not, he would have changed his mind during the bikeshedding process when 80% of the people paying attention argued against it. It’s not even that people have decided that reading code is more important than writing it (or that the novice learning curve matters), After all, sometimes brevity is better for reading, too. So there’s still a balance. It’s just that the balance in the 70s was based on reading and writing on slow teletypes where you had to fit your program into a few KB, while now you have all the screen space and storage you could want and instantaneous auto-complete and so on, so the cost of longer names is a lot lower. And, while Python isn’t quite _that_ old, the balance in Python 0.9 was about fitting in with C in a Unix-ish system, while now Python is about being good for everything from scripts to servers. That’s why we usually get names like `get_current_loop` today instead of names like `getcwd`. (But not always—e.g., new additions to `math` that wrap or emulate `math.h` functions still get C-style names.)
So we don't have to have this entire discussion the next time this comes up, I've posted a summary here: https://pythonchb.github.io/PythonListsSummaries/python_ideas/better_name.ht... Please feel free to link to that the next time :-) Better yet, contribute more summaries to the common issues that come up on this list. -CHB On Fri, Nov 29, 2019 at 9:32 PM Andrew Barnert via Python-ideas < python-ideas@python.org> wrote:
On Nov 29, 2019, at 02:42, Steven D'Aprano <steve@pearwood.info> wrote:
Programming uses lots of initialisms, abbreviations and hybrid words, such as:
os ram ssd dir json xml len chr EOF I/O rlcompleter pprint sqlite
etc, and loads is not particularly worse than the rest.
I agree with your sentiment; and I’m -1 on the change, but it’s worth pointing out that the amount of abbreviation and portmanteuing that’s considered appropriate has changed over the years. The names Guido gave things in 1991 aren’t necessarily the names he’d come up with today; if he were inventing `loads` 28 years later, I think he would have called it `load_string`. And, if not, he would have changed his mind during the bikeshedding process when 80% of the people paying attention argued against it.
It’s not even that people have decided that reading code is more important than writing it (or that the novice learning curve matters), After all, sometimes brevity is better for reading, too. So there’s still a balance. It’s just that the balance in the 70s was based on reading and writing on slow teletypes where you had to fit your program into a few KB, while now you have all the screen space and storage you could want and instantaneous auto-complete and so on, so the cost of longer names is a lot lower. And, while Python isn’t quite _that_ old, the balance in Python 0.9 was about fitting in with C in a Unix-ish system, while now Python is about being good for everything from scripts to servers. That’s why we usually get names like `get_current_loop` today instead of names like `getcwd`. (But not always—e.g., new additions to `math` that wrap or emulate `math.h` functions still get C-style names.) _______________________________________________ Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-leave@python.org https://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/OBBXT7... Code of Conduct: http://python.org/psf/codeofconduct/
-- Christopher Barker, PhD Python Language Consulting - Teaching - Scientific Software Development - Desktop GUI and Web Development - wxPython, numpy, scipy, Cython
Steven D'Aprano writes:
He describes his design of the language here:
We're talking about different things. Specifically:
"Design with learning in mind" literally means "don't forget about beginners in Python and in programming", not "sacrifice everything else on the altar of education".
That's not what it *literally* means.
You're confusing "literally" with "idiomatically". "Design with learning in mind" doesn't say *anything* about what else is in mind, or relative priority. *Idiomatically*, yes, it's used as you and Abdur-Rahmaan have. But *literally* it means that when you're thinking about design, "learning" is in there with all that other stuff. Guido literally quotes the Zen of Python as his design principles. Of the 19 verses, only the two concerned with timing ("now" vs. "right now") are not clearly related to the language being learnable. The fact that Tim didn't explicitly use words like "learning" or "education" in the Zen doesn't mean that Guido hasn't had "learning in mind" when he actually conducted design. The only way we can be sure is to ask him, but I'm willing to stand on the inference from the language we actually have.
In any case, it is a matter of historical fact (to the degree that we believe Guido's account, and we have no reason to think that he is lying) that he didn't design Python with beginners in mind.
Specious. Beginners are not the only people who have need to learn.
One of those concepts he intentionally rejected was that the user had no prior experience and was learning how to program.
You have a *very* restrictive idea of what "learning" means in the context of programming. Not everything that makes a concept learnable is useful or necessary for beginners, not everything that is useful or necessary for beginners is useless for experts. It is of course true that teaching beginning concepts to beginners and advanced concepts to experts are very different activities and benefit from different approaches. That doesn't at all mean that the same set of principles aren't conducive to learning at all levels. It doesn't necessarily mean that they are. But I believe that such a set can be, and that Python's set of design principles as embodied in the Zen as well as some other folk sayings is an example of a set of principles that leads to a language that is conducive to learning. In several domains: about the language itself, about the generic activity of programming, and about the real systems that our programs simulate or implement. Steve
Abdur-Rahmaan Janhangeer http://www.pythonmembers.club | https://github.com/Abdur-rahmaanJ Mauritius On Sat, 30 Nov 2019, 09:36 Christopher Barker, <pythonchb@gmail.com> wrote:
So we don't have to have this entire discussion the next time this comes up, I've posted a summary here:
https://pythonchb.github.io/PythonListsSummaries/python_ideas/better_name.ht...
+1
Why, we could even number them, call them Python-Issues Common Threads, abbreviate that as "PICT", and then refer to them as, e.g., "PICT-114"!! :-D :-D :-D :-D ... |-[
On Sat, 30 Nov 2019 at 10:57, Brian Skinn <brian.skinn@gmail.com> wrote:
Why, we could even number them, call them Python-Issues Common Threads, abbreviate that as "PICT", and then refer to them as, e.g., "PICT-114"!! :-D :-D :-D :-D ... |-[
I nominate this statement for the position of PICT-001 :-) Paul
Abdur-Rahmaan Janhangeer writes:
Education is one side of it. It's about intuitive API
Problem is, just the reactions to examples given in this thread demonstrate that personal intuition varies substantially. To identify the "intuitions" that reach the largest audience, the only halfway objective measure I can think of is to try it out on a large number of new users, which is another way of saying "in an educational context." Why "new" users? Because experienced users will have their "intuition" informed by their experience with "traditional" ways of expression as codified in identifiers and syntax. For example, while augmented assignment turns out to be useful to provide mutating operations and signal them to the reader, the increment operation is purely syntactic sugar compared to "i += 1" as a statement, but insufficiently powerful and orthogonal as an expression to add to Python. Yet C-experienced users frequently requested the increment operator. Similarly, Guido resisted an expression form of assignment for more than a decade, for good reason (at least according to *his* intuition), and finally came to support it when persuasive use cases other than "while i := i + 1:" were proposed. The same kinds of effects will occur for "within Python" tradition. So the purest "intuition" can presumably be observed with new programmers, while experienced programmers new to Python will at least not be steeped in Python's traditional Kool-Aid. Steve
Christopher Barker writes:
Frankly, I get confused when there are discussion on this list (or python-dev, or) about currently PEPs in the midst of active discussion!
I would take that as a signal to ignore that thread or poster, to be honest. If it's not clear from thread and post context what they're talking about, either I didn't really care in the first place and probably shouldn't waste time on it, or they are confused, not me. YMMV, but I consider that good advice.
Is is THAT hard to add a little text?
No. Thing is, I'm not going to go to the effort to do it, mostly because I'm old, set in my ways, and I'm rarely going to think of it unless a bunch of folks are willing to try to train me (which to be effective would probably involve behavior that will get them CoC'd). I suspect more or less the same is true of others with the habit. And in fact, it's so easy a machine can do it. Mailman is a Python application, it would be easy to add that function to either the Decorate handler (which adds text to the body) or put it in a separate handler. The Mailman API is easy enough, you just need a Handler subclass with a process() method which calls (or implements directly) that function. How about one of you number-haters being a hero and writing a Mailman Handler? I'll be happy to answer questions, and make sure it gets added to contrib. Bonus points for recognizing titles or substantial prefixes thereof, and adding the PEP number. ;-) Steve
I'd like to propose potentially adding my comments about strategies for learning APIs and typing through type annotations and introspection tooling with a potential PR to PICT-001. If there's interest, I'll consider preparing a PR? On Saturday, November 30, 2019, Paul Moore <p.f.moore@gmail.com> wrote:
On Sat, 30 Nov 2019 at 10:57, Brian Skinn <brian.skinn@gmail.com> wrote:
Why, we could even number them, call them Python-Issues Common Threads,
abbreviate that as "PICT", and then refer to them as, e.g., "PICT-114"!! :-D :-D :-D :-D ... |-[
I nominate this statement for the position of PICT-001 :-)
Paul _______________________________________________ Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-leave@python.org https://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/2BZ74W... Code of Conduct: http://python.org/psf/codeofconduct/
Though, PICT-001 should probably be reserved as an index for other PICT documents. On Saturday, November 30, 2019, Paul Moore <p.f.moore@gmail.com> wrote:
On Sat, 30 Nov 2019 at 10:57, Brian Skinn <brian.skinn@gmail.com> wrote:
Why, we could even number them, call them Python-Issues Common Threads,
abbreviate that as "PICT", and then refer to them as, e.g., "PICT-114"!! :-D :-D :-D :-D ... |-[
I nominate this statement for the position of PICT-001 :-)
Paul _______________________________________________ Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-leave@python.org https://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/2BZ74W... Code of Conduct: http://python.org/psf/codeofconduct/
That would be PICT-000 (PEP 0 is the index) On 11/30/19 8:25 AM, Wes Turner wrote:
Though, PICT-001 should probably be reserved as an index for other PICT documents.
On Saturday, November 30, 2019, Paul Moore <p.f.moore@gmail.com <mailto:p.f.moore@gmail.com>> wrote:
On Sat, 30 Nov 2019 at 10:57, Brian Skinn <brian.skinn@gmail.com <mailto:brian.skinn@gmail.com>> wrote:
Why, we could even number them, call them Python-Issues Common
Threads, abbreviate that as "PICT", and then refer to them as, e.g., "PICT-114"!! :-D :-D :-D :-D ... |-[
I nominate this statement for the position of PICT-001 :-)
Paul
-- Richard Damon
It sounds like many would agree that renaming some things could have many benefits, but the cost seems to be higher than I imagined. What if an easier way could be created to manage renaming that avoided many of these problems? Perhaps aliases of objects could be something worth baking into the language itself. I don't mean having multiple names pointing to the same object as we can do today, but something new entirely. *THE FOLLOWING IS PROBABLY A CRACKPOT IDEA*, hear it out of you are in the mood to humor me on this Saturday morning. What if the __dict__ for modules and classes could be something like a ChainMap, with multiple internal lookup mappings. The first level (by which I mean, the first mapping consulted) would be the same as exists today, but the second would contain a weak value dictionary with aliases pointing to objects so that when you do json.load_str, it returns json.loads object just like it would if you had added the alias in the way you would today. But the dict is weak value so that if an object is garbage collected, its alias entries are removed. So the second mapping would be a so called "alias dictionary". How could this be done to overcome some of the same objections raised? *First, regarding discoverability: * dir() would work identically to as it does today, but you could give an argument to also provide aliases, something like:
dir(json, alias=True) ['JSONDecodeError', 'JSONDecoder', 'JSONEncoder', '__all__', '__author__', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__path__', '__spec__', '__version__', '_default_decoder', '_default_encoder', 'codecs', 'decoder', 'detect_encoding', 'dump', 'dumps [dump_str]', 'encoder', 'load', 'loads [load_str]', 'scanner']
Note that when you tell dir() that alias=True, additional aliases for objects are added to the output in the form of a string-ified list. Also change the default object repr so that it says something like:
json.loads <function loads (alias: load_str) at 0x.... >
The help() could be modified to be something like:
help(json.load_str)
Help on function loads in module json (alias: load_str): ... *Second objection: "people are going to be confused because now they will ask 'What is the difference between these TWO functions, or between these TWO methods?'":* There are no longer "two different functions/methods". Since aliases are something baked into the language, both new and old folks would need to learn to be GENERALLY aware that they exist, and there will need to be an easy way to retrieve the aliases for an object. So there's a big new thing to learn there. But once that exists, it mostly becomes a single point of learning. People would still periodically see the different names in code and ask the question "what's the difference" of course, but the answer would change. Instead of simply "oh it is the same function with a second name", the answer would be "those are a thing called python aliases; here is a link to the docs talking about how to find aliases". The docs for the object would also list aliases (if there are any). However I dare say you'd probably get this question less often because of the repl output I am suggesting above. *Third objection: it polluts the namespace.* It still would do this to a degree, but I think in a more tolerable way. Most importantly, it seems like it would be preferred for * importing everything from a module to import only the first level dictionary and not all the aliases. Additionally, you can still add or monkeypatch new objects into a namespace (they would go into the first level dictionary, therefore overriding any aliases in the second level). Beyond that, since I'm talking about something new baked into the language, the code writing tools would be updated to know about aliases and provide useful auto complete functionality that makes it clear this is an alias. But yes, of course I knowledge there would definitely be the possibility of bugs created by an accidental typo that happened to also be an alias. *For convenient addition of aliases and discovering them for a specific member: * There are likely all sorts of ways you could do this. Perhaps a dunder alias combined with an alias decorator could be added (probably in functools? not top level)? You could add an alias like: @functools.alias("load_str") def loads(...): ... assert loads.__alias__ == ["load_str"] class MyClass: @functools.alias("prof") def process_file(self, ...): ... assert MyClass.process_file.__alias__ == ["prof"] I'm sure this is an extreme idea and likely nobody is going to be interested. But I started writing it and couldn't stop.
What happens when aliases collide with proper attributes? Could you have an attribute 'foo', combined with an attribute 'bar' with alias 'foo'? If so, how would that work? What happens when a subclass of Foo adds an attribute that masks an alias defined for an attribute of Foo? Dragons. Complicated dragons. -1
What happens when aliases collide with proper attributes? Could you have an attribute 'foo', combined with an attribute 'bar' with alias 'foo'? If so, how would that work?
Using a ChainMap makes this choice for us. The first level dictionary-- which would contain the attribute with the name collision-- wins.
What happens when a subclass of Foo adds an attribute that masks an alias defined for an attribute of Foo?
Again, the child attribute wins because ChainMap.
Ah, right -- relatively straightforward rule. But, one that's going to require a lot of careful thought to track down exactly how a name will resolve across an inheritance tree. Seems like a lot of extra complexity and potential for confusion for a comparatively small benefit. Also, I have to think this would be appreciably slower than the current mechanism, having to run through this ChainMap cascade for (almost) *every* attribute lookup?
On 2019-11-30 05:28, Andrew Barnert via Python-ideas wrote:
On Nov 29, 2019, at 02:42, Steven D'Aprano <steve@pearwood.info> wrote:
Programming uses lots of initialisms, abbreviations and hybrid words, such as:
os ram ssd dir json xml len chr EOF I/O rlcompleter pprint sqlite
etc, and loads is not particularly worse than the rest.
I agree with your sentiment; and I’m -1 on the change, but it’s worth pointing out that the amount of abbreviation and portmanteuing that’s considered appropriate has changed over the years. The names Guido gave things in 1991 aren’t necessarily the names he’d come up with today; if he were inventing `loads` 28 years later, I think he would have called it `load_string`. And, if not, he would have changed his mind during the bikeshedding process when 80% of the people paying attention argued against it.
It’s not even that people have decided that reading code is more important than writing it (or that the novice learning curve matters), After all, sometimes brevity is better for reading, too. So there’s still a balance. It’s just that the balance in the 70s was based on reading and writing on slow teletypes where you had to fit your program into a few KB, while now you have all the screen space and storage you could want and instantaneous auto-complete and so on, so the cost of longer names is a lot lower. And, while Python isn’t quite _that_ old, the balance in Python 0.9 was about fitting in with C in a Unix-ish system, while now Python is about being good for everything from scripts to servers. That’s why we usually get names like `get_current_loop` today instead of names like `getcwd`. (But not always—e.g., new additions to `math` that wrap or emulate `math.h` functions still get C-style names.)
I wouldn't like it if the names got too long. I find a certain amount of abbreviation makes it easier to read in the long run.
Also, I have to think this would be appreciably slower than the current mechanism, having to run through this ChainMap cascade for (almost) *every* attribute lookup?
If I remember correctly, ChainMap is pretty fast. I doubt it would be appreciably slower, though it would undoubtedly be some amount slower in at least some cases. For modules: no, the second level mapping would only be consulted in cases that the name wasn't found in the first level. There would be a very minor speed hit due to the ChainMap overhead, probably not anything anyone would worry about. Consulting two dictionaries instead of one is a very very very minor penalty. For classes, it's worse: the successive alias mappings would be consulted at each level of the MRO in cases a name wasn't found in the normal attribute dict for the first member of the MRO, which is certainly going to be *much* of the time. How bad a hit is this? It would depend on how long the MRO is; it would double the number of dict lookups for any given attribute lookup. Is that an appreciable slow down? I don't know. I kind of doubt it though.
On Nov 30, 2019, at 05:10, Stephen J. Turnbull <turnbull.stephen.fw@u.tsukuba.ac.jp> wrote:
Why "new" users? Because experienced users will have their "intuition" informed by their experience with "traditional" ways of expression as codified in identifiers and syntax. For example, while augmented assignment turns out to be useful to provide mutating operations and signal them to the reader, the increment operation is purely syntactic sugar compared to "i += 1" as a statement, but insufficiently powerful and orthogonal as an expression to add to Python. Yet C-experienced users frequently requested the increment operator.
I’m not sure this example really argues the case. To an experienced C programmer, both += and ++ are intuitive. But to a novice who’s never programmed, neither one is intuitive. The way to distinguish between them is to delve into the C programmers’ intuition and understand what drives it. First, ++ is used almost entirely as an expression in C, and the postfix form is only useful as an expression, but += is often used as a statement. But Python expressions (for the next few decades until :=, at least) normally don’t mutate things, except for explicit method calls which by convention return None. So neither of them should be an expression in Python, which is a strike against the C intuition for usability of ++ being transferable to Python, but not against +=. Furthermore, ++ is only useful on index-like values, and, unlike C, all of these are immutable in Python (at least until someone invents numpy index arrays as indexes), while += is useful on all numeric-like and sequence-like values, and the prototypical sequence-like type, list, is mutable. This is another strike against ++ but not +=. Of course that’s only two strikes. But now, when you’re balancing the cost (two extra methods, one of which is mildly confusing, vs. one, and prefix ++ requires an extra lookahead to distinguish from prefix +, but += and postfix ++ don’t) against the benefit… I don’t think Guido actually went through all of this in conscious detail, much less on paper (the way we would if someone were proposing ++ and += in the age of PEPs and -ideas and -dev), but I think it’s the main underlying reason he decided that borrowing += but not ++ made sense for Python. Not imagining whether new users would clamor first += but not ++, or be able to learn each when they see it, but knowing that C programmers would find them both intuitive but that their intuition for ++ doesn’t make sense for Python while their intuition for += does.
On Nov 30, 2019, at 08:02, Ricky Teachey <ricky@teachey.org> wrote:
It sounds like many would agree that renaming some things could have many benefits, but the cost seems to be higher than I imagined.
What if an easier way could be created to manage renaming that avoided many of these problems?
Perhaps aliases of objects could be something worth baking into the language itself. I don't mean having multiple names pointing to the same object as we can do today, but something new entirely.
Are you suggesting we allow this so users/projects can add their own aliases into the stdlib, or so that the stdlib can grow a whole mess of aliases?
THE FOLLOWING IS PROBABLY A CRACKPOT IDEA, hear it out of you are in the mood to humor me on this Saturday morning.
What if the __dict__ for modules and classes could be something like a ChainMap, with multiple internal lookup mappings. The first level (by which I mean, the first mapping consulted) would be the same as exists today, but the second would contain a weak value dictionary with aliases pointing to objects so that when you do json.load_str, it returns json.loads object just like it would if you had added the alias in the way you would today. But the dict is weak value so that if an object is garbage collected, its alias entries are removed.
So if you monkeypatch json.loads, its last reference might go away, in which case json.load_str becomes a dead weakref and can no longer be used? What’s the benefit of that? Wouldn’t it be better to make load_str alias loads by name, so if an existing module monkeypatches loads, it automatically changes load_str as well?
So the second mapping would be a so called "alias dictionary".
How could this be done to overcome some of the same objections raised?
First, regarding discoverability:
dir() would work identically to as it does today, but you could give an argument to also provide aliases, something like:
dir(json, alias=True) ['JSONDecodeError', 'JSONDecoder', 'JSONEncoder', '__all__', '__author__', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__path__', '__spec__', '__version__', '_default_decoder', '_default_encoder', 'codecs', 'decoder', 'detect_encoding', 'dump', 'dumps [dump_str]', 'encoder', 'load', 'loads [load_str]', 'scanner']
Note that when you tell dir() that alias=True, additional aliases for objects are added to the output in the form of a string-ified list.
But not the same as actually stringifying a list, which gives you the reprs of its members. Also, this means tools now have to understand how to parse this language; you can’t just do `for name in dir(spam): something(name)`, you have to do something like: for name in dir(spam, alias=True): if match := re.match(r'(\w+) \[(.*?)\])', name): something(match.groups(1)) for alias in groups(2).split(', '): something(alias) else: something(name) Of course you could write a helper function to do the heavy lifting, but it’s still going to be nontrivial. And all existing tools that rely on dir (e.g., to autocomplete in a REPL or IDE, or to build a proxy object that exposes the same names) aren’t going to see aliases until they’re changed to do this.
Also change the default object repr so that it says something like:
json.loads <function loads (alias: load_str) at 0x.... >
How does it even know that? Does it have to look at its module and name, then look at the module’s alias dict?
Most importantly, it seems like it would be preferred for * importing everything from a module to import only the first level dictionary and not all the aliases.
Doesn’t that defeat the purpose of aliases? If you don’t have them at the REPL when you * import, you’re going to learn the “unintuitive” name that is available, instead of learning the “intuitive” one. Also, won’t it be at least annoying, if not confusing, if the help, dir, and repr mention the alias but you can’t use it?
Additionally, you can still add or monkeypatch new objects into a namespace (they would go into the first level dictionary, therefore overriding any aliases in the second level). Beyond that, since I'm talking about something new baked into the language, the code writing tools would be updated to know about aliases and provide useful auto complete functionality that makes it clear this is an alias.
How are you imagining that working? When you autocomplete in the standard REPL or ipython or bpython or PyCharm or PyDev, what will they do to indicate that it’s an alias?
For convenient addition of aliases and discovering them for a specific member:
There are likely all sorts of ways you could do this. Perhaps a dunder alias combined with an alias decorator could be added (probably in functools? not top level)?
You could add an alias like:
@functools.alias("load_str") def loads(...): ...
assert loads.__alias__ == ["load_str"]
Is this dunder a @property that looks at the module’s alias namespace? Or is it actually a copy of the same information? If so, how are they kept in sync? (Or is that just a “consenting adults” thing—if you only add aliases with the decorator the two are in sync, but if you don’t, you have to do it right manually or you’ll confuse people.)
class MyClass: @functools.alias("prof") def process_file(self, ...): ...
assert MyClass.process_file.__alias__ == ["prof"]
So classes also have an alias dict? And presumably their dir also changes? And unbound methods obviously have aliases (because they’re just functions), but what about bound methods (and classmethods and custom method-y decorators)? For example, if `mine = MyClass()`, does `mine.process_file.__alias__` also work? How? Do method objects have a @property for the dunder that delegates to the underlying `__func__`? If not, I don’t think this would be very useful. You’d also need to rewrite what __getatrribute__ does to look at aliases on the class and base classes (and on the object, or is that not allowed?), which would break most existing custom __getattribute__ methods.
On Nov 30, 2019, at 10:25, MRAB <python@mrabarnett.plus.com> wrote:
On 2019-11-30 05:28, Andrew Barnert via Python-ideas wrote:
On Nov 29, 2019, at 02:42, Steven D'Aprano <steve@pearwood.info> wrote: Programming uses lots of initialisms, abbreviations and hybrid words, such as: os ram ssd dir json xml len chr EOF I/O rlcompleter pprint sqlite etc, and loads is not particularly worse than the rest. I agree with your sentiment; and I’m -1 on the change, but it’s worth pointing out that the amount of abbreviation and portmanteuing that’s considered appropriate has changed over the years. The names Guido gave things in 1991 aren’t necessarily the names he’d come up with today; if he were inventing `loads` 28 years later, I think he would have called it `load_string`. And, if not, he would have changed his mind during the bikeshedding process when 80% of the people paying attention argued against it. It’s not even that people have decided that reading code is more important than writing it (or that the novice learning curve matters), After all, sometimes brevity is better for reading, too. So there’s still a balance. It’s just that the balance in the 70s was based on reading and writing on slow teletypes where you had to fit your program into a few KB, while now you have all the screen space and storage you could want and instantaneous auto-complete and so on, so the cost of longer names is a lot lower. And, while Python isn’t quite _that_ old, the balance in Python 0.9 was about fitting in with C in a Unix-ish system, while now Python is about being good for everything from scripts to servers. That’s why we usually get names like `get_current_loop` today instead of names like `getcwd`. (But not always—e.g., new additions to `math` that wrap or emulate `math.h` functions still get C-style names.) I wouldn't like it if the names got too long. I find a certain amount of abbreviation makes it easier to read in the long run.
Sure. That’s why I said “After all, sometimes brevity is better for reading too. So there’s still a balance.” I’m not suggesting that the default has shifted all the way to spelling out everything, or that it ever will, much less arguing that we should change it. Just pointing out that we spell things out _more_ in 2019 Python than we did in 1978 C or even 1991 Python, and we probably wouldn’t have spelled this function `loads` if it were part of a new module added today rather than part of marshal added in 1.x.
On 1/12/19 8:54 am, Andrew Barnert via Python-ideas wrote:
but that their intuition for ++ doesn’t make sense for Python while their intuition for += does.
Another couple of possible reasons: * There is far less use for ++ in Python. In C, it's extremely common to step through arrays by incrementing indices or pointers, but Python has higher-level ways of doing most of those things. * Prefix ++ already has a meaning (two applications of prefix +) so it would have been a backwards-incompatible change. -- Greg
On Sat, Nov 30, 2019 at 01:30:55PM -0500, Ricky Teachey wrote:
Consulting two dictionaries instead of one is a very very very minor penalty.
It's more than twice as expensive: not only do you have to do two look ups rather than one, but you have to also look up the second dict as well. And there's the overhead of the ChainMap itself. $ ./python -m timeit -s "d = {}" "d.get('aardvark')" 500000 loops, best of 5: 702 nsec per loop $ ./python -m timeit -s "from collections import ChainMap" -s "d = ChainMap([{}, {}])" "d.get('aardvark')" 20000 loops, best of 5: 12.3 usec per loop That's 17 times slower on my PC. -- Steven
On Sat, Nov 30, 2019 at 3:02 AM Brian Skinn <brian.skinn@gmail.com> wrote:
That aside, absolutely +1 for curating such a list. Excellent idea.
Thanks -- I hope you'll be able to contribute. -CHB
_______________________________________________ Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-leave@python.org https://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/4W3WDQ... Code of Conduct: http://python.org/psf/codeofconduct/
-- Christopher Barker, PhD Python Language Consulting - Teaching - Scientific Software Development - Desktop GUI and Web Development - wxPython, numpy, scipy, Cython
On Sat, Nov 30, 2019 at 06:21:29PM +0000, MRAB wrote:
I wouldn't like it if the names got too long. I find a certain amount of abbreviation makes it easier to read in the long run.
This. People are beginners for what, maybe 2 or 5% of their career as programmers? The minor benefit they get at their beginning of their career from reading "load_from_string" instead of "loads" is outweighed twenty times over by the cost of having to read "load_from_string" instead of "loads" for the rest of their career. There's a reason why fluent English speakers prefer short words like "car" or "bus" over long words like "automobile" and "omnibus". (German speakers may disagree.) -- Steven
On Sat, Nov 30, 2019 at 11:54:35AM -0800, Andrew Barnert via Python-ideas wrote:
To an experienced C programmer, both += and ++ are intuitive. But to a novice who’s never programmed, neither one is intuitive.
Can we have a moratorium on the use of the word "intuitive" until people learn to stop misusing it for "things people have learned to expect"? Neither += or ++ are intuitive to C programmers, or anyone else. You wouldn't say that the meaning of "python" was intuitive would you? Or driving a car? intuitive adj 1: spontaneously derived from or prompted by a natural tendency; "an intuitive revulsion" 2: obtained through intuition rather than from reasoning or observation [syn: intuitive, nonrational, visceral] I think you are talking about reading of words/symbols which, through long use, have become second-nature. The reader has become accustomed to the symbol, and understands it without having to consciously think about it. The most accurate term is probably "conditioned response", the very opposition of intuition, but that's a bit jargony. -- Steven
Me too. I'm a relative python-ideas newb, though, so I don't really know the back catalog. On Sat, Nov 30, 2019, 18:46 Christopher Barker <pythonchb@gmail.com> wrote:
On Sat, Nov 30, 2019 at 3:02 AM Brian Skinn <brian.skinn@gmail.com> wrote:
That aside, absolutely +1 for curating such a list. Excellent idea.
Thanks -- I hope you'll be able to contribute.
-CHB
_______________________________________________ Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-leave@python.org https://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/4W3WDQ... Code of Conduct: http://python.org/psf/codeofconduct/
-- Christopher Barker, PhD
Python Language Consulting - Teaching - Scientific Software Development - Desktop GUI and Web Development - wxPython, numpy, scipy, Cython
Consulting two dictionaries instead of one is a very very very
minor penalty.
It's more than twice as expensive: not only do you have to do two look ups rather than one, but you have to also look up the second dict as well. And there's the overhead of the ChainMap itself.
$ ./python -m timeit -s "d = {}" "d.get('aardvark')" 500000 loops, best of 5: 702 nsec per loop
$ ./python -m timeit -s "from collections import ChainMap" -s "d = ChainMap([{}, {}])" "d.get('aardvark')" 20000 loops, best of 5: 12.3 usec per loop
That's 17 times slower on my PC.
Well that's the death rattle on that particular crackpot idea.
On Nov 30, 2019, at 16:15, Steven D'Aprano <steve@pearwood.info> wrote:
On Sat, Nov 30, 2019 at 11:54:35AM -0800, Andrew Barnert via Python-ideas wrote:
To an experienced C programmer, both += and ++ are intuitive. But to a novice who’s never programmed, neither one is intuitive.
Can we have a moratorium on the use of the word "intuitive" until people learn to stop misusing it for "things people have learned to expect"?
It’s not “things people have learned to expect”, it’s “things people apprehend without having to think consciously”. Which is what “intuitive” means. It doesn’t matter whether that intuition is pre-wired instinct or conditioning or intellectual learning or some neurotic mistake.
Neither += or ++ are intuitive to C programmers, or anyone else. You wouldn't say that the meaning of "python" was intuitive would you? Or driving a car?
Yes. There are books about intuitive design that talk about why you wouldn’t make a new left-side-drive car with the gas pedal on the left. Why? Because that would violate drivers’ intuitions.
intuitive adj 1: spontaneously derived from or prompted by a natural tendency; "an intuitive revulsion" 2: obtained through intuition rather than from reasoning or observation [syn: intuitive, nonrational, visceral]
What dictionary gives “intuitive” as a synonym for itself? The first definition on Wiktionary is “Spontaneous, without requiring conscious thought”. You used “The reader has become accustomed to the symbol, and understands it without having to consciously think about it” as a description of whatever-it-is to contrast with intuition, but it is intuition. When you apprehend something without being conscious of how you got there, that’s intuition. Even using your definition: How does a C programmers understand that `x += 2`? It’s not by reasoning or observation; it’s by knowing what += means without having to reason it through. (It’s definitely not a conditioned response, as you suggested later, unless you’re a hardcore behaviorist who believes that things like responding in a conversation or writing code are directly mediated by external stimuli.)
I think you are talking about reading of words/symbols which, through long use, have become second-nature.
I was quoting Stephen, who wrote a whole long email explaining what he was talking about. Admittedly he did use scare quotes, but I don’t think they were needed. Since we’re talking about programming languages, it’s worth looking next door at how mathematicians (and philosophers of math) use the word. When they talk about the need to get a new construction into their intuition so they can play with it, they’re not talking about needing a time machine to go back and change human history so they will have been born pre-wired to get this construction “naturally”, they’re talking about learning it to the point where using it feels the same as the things that were pre-wired, like (maybe) counting. When you can read XYX^-1 and understand what it means without having to translate it to the low-level matrix multiplication rules and work it out, you understand matrix multiplication intuitively. (Of course there are people who disagree with this view of math—including the ones that call themselves intuitionists—but their disagreement assumes the same notion of intuitive; they just believe things like infinity can’t possibly be intuitive, and therefore most mathematicians must be fooling themselves about what they “know”. ) But yes, learning things until they become second-nature (at least learning how to use things, as opposed to learning about them) is exactly what getting things into your intuition means, not just for math but for everything. If you want to, you can get prescriptivist and argue that mathematicians and everyone else are misusing the word (and Wiktionary shouldn’t be endorsing this destruction of our language), but if you look at the history back to the original etymology, it’s always been about “look at it and get it”, not about whether that ability was inborn, conditioned, or learned intellectually.
On 1/12/19 5:00 am, Ricky Teachey wrote:
Perhaps aliases of objects could be something worth baking into the language itself.
We would have to be using aliases a *lot* to make something like this worthwhile. I don't think that's something we should be doing or encouraging. Also, for the use case being considered -- renaming functions and methods -- garbage collection is hardly an issue. If you want the help for an alias to be different from the thing it aliases, you can achieve that now using a stub function that delegates to the replacement. -- Greg
Abdur-Rahmaan Janhangeer http://www.pythonmembers.club | https://github.com/Abdur-rahmaanJ Mauritius On Thu, 28 Nov 2019, 15:24 Abdur-Rahmaan Janhangeer, <arj.python@gmail.com> wrote:
"Designed With Learning in Mind"
I had no idea Guido told that or Python vowed that but thought it was a cool concept to design APIs with teachability in mind.
On Sat, Nov 30, 2019 at 05:31:01PM -0800, Andrew Barnert wrote:
On Nov 30, 2019, at 16:15, Steven D'Aprano <steve@pearwood.info> wrote:
On Sat, Nov 30, 2019 at 11:54:35AM -0800, Andrew Barnert via Python-ideas wrote:
To an experienced C programmer, both += and ++ are intuitive. But to a novice who’s never programmed, neither one is intuitive.
Can we have a moratorium on the use of the word "intuitive" until people learn to stop misusing it for "things people have learned to expect"?
It’s not “things people have learned to expect”, it’s “things people apprehend without having to think consciously”.
By that definition, reading is "intuitive", so is driving along a route you know well, for experienced pilots so is flying a plane, and for physicists, so is tensor calculus. By that definition, experienced Unix sys admins will consider: find . -type f -perm 777 to be intuitive. By that definition, anything and everything is "intuitive" if you just practice it enough, and the word becomes meaningless. Let's just agree that everything is intuitive, and we're done!
Which is what “intuitive” means.
No it doesn't: lack of conscious thought is a necessary but not sufficient condition.
It doesn’t matter whether that intuition is pre-wired instinct or conditioning or intellectual learning or some neurotic mistake.
Yes it does matter. That's why I will often respond to assertions that "such and such is intuitive" with "intuitive to who?" The bottom line is, the way "intuitive" is used on this mailing list just means "I like it" or "I'm used to it". With very, very few exceptions, I cannot take any argument seriously as soon as people start claiming "X is intuitive" or "Y is unintuitive".
Neither += or ++ are intuitive to C programmers, or anyone else. You wouldn't say that the meaning of "python" was intuitive would you? Or driving a car?
Yes. There are books about intuitive design that talk about why you wouldn’t make a new left-side-drive car with the gas pedal on the left. Why? Because that would violate drivers’ intuitions.
If true, that's a poor reason. A better reason is because it puts the accelerator (where the driver will leave their dominant foot for 90% of the journey) in a less comfortable position. If most people were left-footed, our
intuitive adj 1: spontaneously derived from or prompted by a natural tendency; "an intuitive revulsion" 2: obtained through intuition rather than from reasoning or observation [syn: intuitive, nonrational, visceral]
What dictionary gives “intuitive” as a synonym for itself?
WordNet. It's a bug in their database, that is all.
The first definition on Wiktionary is “Spontaneous, without requiring conscious thought”.
Not any more it doesn't. What's your point? Only kidding. I haven't actually gone and changed the definition, although anyone can. Dictionary definitions don't always capture the nuances of the meaning of words. Often they do a really bad job of it. This is one: the critical aspect of *intuition* isn't just that it doesn't require conscious thought, but that it is *in-built*. c
You used “The reader has become accustomed to the symbol, and understands it without having to consciously think about it” as a description of whatever-it-is to contrast with intuition, but it is intuition. When you apprehend something without being conscious of how you got there, that’s intuition.
Even using your definition: How does a C programmers understand that `x += 2`? It’s not by reasoning or observation; it’s by knowing what += means without having to reason it through.
(It’s definitely not a conditioned response, as you suggested later, unless you’re a hardcore behaviorist who believes that things like responding in a conversation or writing code are directly mediated by external stimuli.)
I think you are talking about reading of words/symbols which, through long use, have become second-nature.
I was quoting Stephen, who wrote a whole long email explaining what he was talking about. Admittedly he did use scare quotes, but I don’t think they were needed.
Since we’re talking about programming languages, it’s worth looking next door at how mathematicians (and philosophers of math) use the word. When they talk about the need to get a new construction into their intuition so they can play with it, they’re not talking about needing a time machine to go back and change human history so they will have been born pre-wired to get this construction “naturally”, they’re talking about learning it to the point where using it feels the same as the things that were pre-wired, like (maybe) counting. When you can read XYX^-1 and understand what it means without having to translate it to the low-level matrix multiplication rules and work it out, you understand matrix multiplication intuitively. (Of course there are people who disagree with this view of math—including the ones that call themselves intuitionists—but their disagreement assumes the same notion of intuitive; they just believe things like infinity can’t possibly be intuitive, and therefore most mathematicians must be fooling themselves about what they “know”. )
But yes, learning things until they become second-nature (at least learning how to use things, as opposed to learning about them) is exactly what getting things into your intuition means, not just for math but for everything.
If you want to, you can get prescriptivist and argue that mathematicians and everyone else are misusing the word (and Wiktionary shouldn’t be endorsing this destruction of our language), but if you look at the history back to the original etymology, it’s always been about “look at it and get it”, not about whether that ability was inborn, conditioned, or learned intellectually.
Does functools.update_wrapper() *copy* __doc__ and __annotations__ or *reference* those function/method attributes so that the API docs have the docstrings and tools with type annotation support have the correct type annotations? https://docs.python.org/3/library/functools.html#functools.update_wrapper On Saturday, November 30, 2019, Greg Ewing <greg.ewing@canterbury.ac.nz> wrote:
On 1/12/19 5:00 am, Ricky Teachey wrote:
Perhaps aliases of objects could be something worth baking into the
language itself.
We would have to be using aliases a *lot* to make something like this worthwhile. I don't think that's something we should be doing or encouraging.
Also, for the use case being considered -- renaming functions and methods -- garbage collection is hardly an issue.
If you want the help for an alias to be different from the thing it aliases, you can achieve that now using a stub function that delegates to the replacement.
-- Greg _______________________________________________ Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-leave@python.org https://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/FEERFE... Code of Conduct: http://python.org/psf/codeofconduct/
Apparently hitting "Send" when I intended to hit "Save" to come back and edit the message further is also "intuitive", since it involved no conscious thought. Sorry about that. Aside from cleaning up or removing some of the unfinished paragraphs, one of the major points I intended to make is that just a few weeks ago we had someone on this list maintaining (if my recollection is correct) that the obscure, cryptic, pseudo-mathematical syntax of APL is "intuitive" and therefore much better than Python's syntax. He was apparently perfectly sincere in this opinion. I'm sticking to my conclusion: people misuse "intuitive" to the point that it is a meaningless term of approval or disapproval. If they like something, they claim it is "intuitive", and if they don't, it's "unintuitive". -- Steven
On Sat, Nov 30, 2019 at 11:13:54PM -0500, Wes Turner wrote:
Does functools.update_wrapper() *copy* __doc__ and __annotations__ or *reference* those function/method attributes so that the API docs have the docstrings and tools with type annotation support have the correct type annotations? https://docs.python.org/3/library/functools.html#functools.update_wrapper
Right at the top of the page is a link to the source code, so you ought to be able to tell from reading the source, which is in Python. I would expect that since __doc__ is a string or None, and in both cases immutable, copying it would be a waste of time. (And impossible in the case of None.) I'm gratified to see from the source that I'm correct: update_wrapper calls: setattr(wrapper, attr, value) not setattr(wrapper, attr, copy.copy(value)) or similar. Does that answer your question? If I have misunderstood your question, please clarify. -- Steven
On Sat, Nov 30, 2019 at 07:40:13PM -0500, Brian Skinn wrote:
Me too. I'm a relative python-ideas newb, though, so I don't really know the back catalog.
In your Copious Spare Time(TM), I can highly recommend randomly browsing the archives looking for subjects which seem interesting to you. I've learned a lot by doing so. Here are the old archives: https://mail.python.org/pipermail/python-ideas/ The new "Hyperkitty" interface is here: https://mail.python.org/mailman3/lists/python-ideas.python.org/ (Personally I find the old pipermail interface better for random browsing, but your mileage may vary.) -- Steven
I'm lost in that new mail interfacs, i'm lost, really lost. It's the 'HyperTrippy' version. Abdur-Rahmaan Janhangeer http://www.pythonmembers.club | https://github.com/Abdur-rahmaanJ Mauritius
On Nov 30, 2019, at 20:13, Steven D'Aprano <steve@pearwood.info> wrote:
On Sat, Nov 30, 2019 at 05:31:01PM -0800, Andrew Barnert wrote:
On Nov 30, 2019, at 16:15, Steven D'Aprano <steve@pearwood.info> wrote: On Sat, Nov 30, 2019 at 11:54:35AM -0800, Andrew Barnert via Python-ideas wrote:
To an experienced C programmer, both += and ++ are intuitive. But to a novice who’s never programmed, neither one is intuitive.
Can we have a moratorium on the use of the word "intuitive" until people learn to stop misusing it for "things people have learned to expect"?
It’s not “things people have learned to expect”, it’s “things people apprehend without having to think consciously”.
By that definition, reading is "intuitive", so is driving along a route you know well, for experienced pilots so is flying a plane, and for physicists, so is tensor calculus.
Yes. But reading is not intuitive for people who are semi-literate and have to think through each word, and tensor calculus is not intuitive for undergrad physics students. Very little is intuitive to everyone or to no one. Speaking a language is intuitive for almost all adults, but only because we’ve almost all learned one—people who were raised by wolves don’t find language intuitive. But that doesn’t make the word useless. For one thing, while conceptually anything could be intuitive to a given person, most things are not, so it’s a useful question whether a specific thing actually is. And, more importantly, something can be intuitive to (almost all of) a community: native English speakers, Python programmers, drivers, whatever. (If you’re worried about the “almost” there, that’s no more a problem than the fact that we can say that English is a language even though no two people have the same idiolect, and cats are a species, and so on.) When someone says “that’s not intuitive”, they usually have such a community in mind, and they’re assuming you have the same community in mind.
By that definition, experienced Unix sys admins will consider:
find . -type f -perm 777
to be intuitive.
Probably, yes. And if they do, they’re right. Whether something is intuitive to you is usually available to introspection.
Which is what “intuitive” means.
No it doesn't: lack of conscious thought is a necessary but not sufficient condition.
I think you’re mixing up “intuitive” with some other word. Maybe “innate” or “instinctive”?
It doesn’t matter whether that intuition is pre-wired instinct or conditioning or intellectual learning or some neurotic mistake.
Yes it does matter. That's why I will often respond to assertions that "such and such is intuitive" with "intuitive to who?"
Well, that means you actually understand, and even use, the normal meaning of the word, even though you’re denying it. By your definition, your question wouldn’t make sense. Nothing about particular strings of letters is innate or instinctive or a priori natural or anything like that. It doesn’t make any sense to ask “intuitive to who?” If the meaning of intuitive inherently requires the answer to always be no one. But with the usual meaning, it not only makes sense, it’s exactly the right question. If it turns out that it’s only intuitive to the person making the proposal (and they hadn’t thought that out), their argument for their proposal fails. If it turns out that it’s intuitive to the vast majority of the Python community and you’re just an oddball for not getting it, your objection fails. Of course usually it’s somewhere in between, but the answer still helps tease out what the actual area for discussion is. (For example, if X is intuitive to most Python web developers, but confusing to a lot of numeric programmers, is it in a library that nobody but web developers are likely to use, or is it a builtin that will affect the numeric programmers too?) And the reason this is an important question is that it’s a very common mistake to mistake “intuitive to me” or “intuitive to this community that I’m part of” for “intuitive to a much larger community”. (It’s not at all a common mistake to mistake “intuitive to nobody, including myself” for “intuitive to a much larger community”.)
The bottom line is, the way "intuitive" is used on this mailing list just means "I like it" or "I'm used to it". With very, very few exceptions, I cannot take any argument seriously as soon as people start claiming "X is intuitive" or "Y is unintuitive".
What you should do is exactly what you just said you’d do a paragraph above: ask “Intuitive to who?”
The first definition on Wiktionary is “Spontaneous, without requiring conscious thought”.
Not any more it doesn't. What's your point?
Only kidding. I haven't actually gone and changed the definition, although anyone can.
Really? Go try blanking the page, or turning it into nonsense, and see how long it lasts before someone discovers and reverts it. (Don’t actually do this; you’re just wasting time for the volunteers, and making it more likely that any real edits you make in the future will be interpreted somewhat hostilely.) Now try submitting a devious patch to the open source library you’re using to access WordNet and see how long it takes before someone discovers and reverts it. (Don’t actually do this either. Also don’t put a cat in a box with a cyanide capsule, raise a child for 18 years in a dark room with no human contact, use the entire nation of China to simulate a human brain, …)
Dictionary definitions don't always capture the nuances of the meaning of words. Often they do a really bad job of it. This is one: the critical aspect of *intuition* isn't just that it doesn't require conscious thought, but that it is *in-built*.
No, it really isn’t. If a mathematician can manipulate multi-dimensional spaces in her mind the same way you can manipulate 3D spaces, does that mean we all have an in-built facility to manipulate 8 dimensions, or that what the mathematician is doing isn’t actually intuitive even if it feels intuitive and leads to intuitive insights? And if playing around with that 8D space leads her to intuit the solution to a problem (but now she has to go back and figure out how to get that same solution deductively so she can prove it), does that mean the solution was built into her mind all along? Or all of our minds? Even Plato didn’t think that. (Freud actually did think that, but he concluded that therefore intuition doesn't make sense and doesn’t exist, which isn’t very helpful.) This isn’t a flaw in the Wiktionary definition and WordNet’s entry and every other dictionary in the world missing nuances. Read Wikipedia or Encyclopedia Brittanica and they’ll say a lot more about intuition (pretty different things about it, actually), but neither one says intuition is innate. In fact, a lot of Wikipedia’s article is about how different philosophical and religious traditions try to handle the idea of knowledge which is neither innate nor taught nor (consciously) rationally worked out (often by recourse to supernatural explanations). If intuition were inherently innate, there would be no such category and no such mystery to solve.
Andrew Barnert via Python-ideas writes:
It’s not “things people have learned to expect”, it’s “things people apprehend without having to think consciously”. Which is what “intuitive” means.
I believe many people make a distinction between unconscious apprehension as perception ("intuition") and unconscious apprehension as memory ("training", "custom", or "habit"). Practically that may be a distinction without a difference, but that's a different argument. This distinction is made, even if you wouldn't.
It doesn’t matter whether that intuition is pre-wired instinct or conditioning or intellectual learning or some neurotic mistake.
I think "pre-wired instinct" is indeed different, though. That will evolve on a different time scale from conditioning, etc (at least, the millennials who made "OK, Boomer" trend think so!) You also omit the mystical "direct grasping" of Zen, which supposes that intuition is an emergent phenomenon of conscious mind. (I don't claim such "direct grasping" exists, or that anyone in this thread does, but there are definitely people who do.) Steve
Andrew Barnert writes:
I’m not sure this example really argues the case.
To an experienced C programmer, both += and ++ are intuitive. But to a novice who’s never programmed, neither one is intuitive.
I'm sorry, I expressed my point poorly, which is, first, that IMHO your statement above is exactly right. In addition, I meant to argue that "+=" got in because as an assignment statement it is useful to express mutation in place, while "++" had no such use. It's an argument which is similar in form but along a different dimension from the one you emphasize. Steve
Well, `json` and the other modules could add another standard: `serialize` and `deserialize` As an example, this is how I deserialize from a custom class: def __init__(self, source): path = None try: # most common case: JSON string self._data_raw = json.loads(source) except TypeError: try: # check if it's a dict-like object source.items self._data_raw = copy.deepcopy(source) except AttributeError: try: # maybe a file object? self._data_raw = json.load(f) except AttributeError: # maybe a PathLike? path = source except JSONDecodeError: # maybe a path string? path = source if path: with open(path) as f: self._data_raw = json.load(f) Apart the `dict` check, this logic could be applied to a `json.deserialize()` function. Python let you function overloading more simple, so why not use it?
I second that.. json.load/loads and json.dump/dumps should be more understandable.. On Thu, 26 Dec, 2019, 04:50 python-ideas--- via Python-ideas, < python-ideas@python.org> wrote:
Well, `json` and the other modules could add another standard: `serialize` and `deserialize`
As an example, this is how I deserialize from a custom class:
def __init__(self, source): path = None
try: # most common case: JSON string self._data_raw = json.loads(source) except TypeError: try: # check if it's a dict-like object source.items self._data_raw = copy.deepcopy(source) except AttributeError: try: # maybe a file object? self._data_raw = json.load(f) except AttributeError: # maybe a PathLike? path = source except JSONDecodeError: # maybe a path string? path = source
if path: with open(path) as f: self._data_raw = json.load(f)
Apart the `dict` check, this logic could be applied to a `json.deserialize()` function. Python let you function overloading more simple, so why not use it? _______________________________________________ Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-leave@python.org https://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/6KZ54W... Code of Conduct: http://python.org/psf/codeofconduct/
participants (19)
-
Abdur-Rahmaan Janhangeer
-
Andrew Barnert
-
Brian Skinn
-
Chris Angelico
-
Christopher Barker
-
Eric V. Smith
-
Greg Ewing
-
Kyle Stanley
-
Michael Selik
-
MRAB
-
Paul Moore
-
python-ideas@marco.sulla.e4ward.com
-
Rhodri James
-
Richard Damon
-
Ricky Teachey
-
Siddharth Prajosh
-
Stephen J. Turnbull
-
Steven D'Aprano
-
Wes Turner