In cases where it makes sense to do explicit type checking (with ABCs or whatever), I really detest the look of the isinstance() function. if isinstance(thing, Fruit) and not isinstance(thing, Apple): Yucky. What I really want to write is: if thing is a Fruit and thing is not an Apple: and after thinking about it on and off for a while I wonder if it might indeed be possible to teach the parser to handle that in a way that eliminates almost all possible ambiguity with the regular "is", including perhaps 100% of all existing standard library code and almost all user code? Maybe this has been considered at some point in the past? The "is [not] a|an" proposal would at least be a strong contender for "hardest thing to search for on the internet" lol. Thanks! Gavin
So this would make `a` a new keyword. I don't think that could be added into python 4 at the earliest because it would immediately break all code for which `a` is a variable name. I can appreciate wanting to make simple operations easy to read, though I think this relies too much on understanding English and wouldn't be intuitive for people who aren't English speaking. I am native English speaking so I wouldn't know for sure, but I think accepting that "or" is the same as "||" is an easier jump to make than "x is a y" being a construct for indicating that x belongs to the y class. If you need this English-style syntax, I believe `type(x) is y` is guaranteed to be True if x is exactly of the y type and not one of its super classes. On Fri, May 1, 2020, 1:27 PM gbs--- via Python-ideas < python-ideas@python.org> wrote:
In cases where it makes sense to do explicit type checking (with ABCs or whatever), I really detest the look of the isinstance() function.
if isinstance(thing, Fruit) and not isinstance(thing, Apple):
Yucky.
What I really want to write is:
if thing is a Fruit and thing is not an Apple:
and after thinking about it on and off for a while I wonder if it might indeed be possible to teach the parser to handle that in a way that eliminates almost all possible ambiguity with the regular "is", including perhaps 100% of all existing standard library code and almost all user code?
Maybe this has been considered at some point in the past? The "is [not] a|an" proposal would at least be a strong contender for "hardest thing to search for on the internet" lol.
Thanks!
Gavin _______________________________________________ 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/YKLNQX... Code of Conduct: http://python.org/psf/codeofconduct/
On 2020-05-01 2:46 p.m., Steele Farnsworth wrote:
So this would make `a` a new keyword. I don't think that could be added into python 4 at the earliest because it would immediately break all code for which `a` is a variable name.
we could have keyphrases instead of keywords, tbh.
I can appreciate wanting to make simple operations easy to read, though I think this relies too much on understanding English and wouldn't be intuitive for people who aren't English speaking. I am native English speaking so I wouldn't know for sure, but I think accepting that "or" is the same as "||" is an easier jump to make than "x is a y" being a construct for indicating that x belongs to the y class.
If you need this English-style syntax, I believe `type(x) is y` is guaranteed to be True if x is exactly of the y type and not one of its super classes.
On Fri, May 1, 2020, 1:27 PM gbs--- via Python-ideas <python-ideas@python.org <mailto:python-ideas@python.org>> wrote:
In cases where it makes sense to do explicit type checking (with ABCs or whatever), I really detest the look of the isinstance() function.
if isinstance(thing, Fruit) and not isinstance(thing, Apple):
Yucky.
What I really want to write is:
if thing is a Fruit and thing is not an Apple:
and after thinking about it on and off for a while I wonder if it might indeed be possible to teach the parser to handle that in a way that eliminates almost all possible ambiguity with the regular "is", including perhaps 100% of all existing standard library code and almost all user code?
Maybe this has been considered at some point in the past? The "is [not] a|an" proposal would at least be a strong contender for "hardest thing to search for on the internet" lol.
Thanks!
Gavin _______________________________________________ Python-ideas mailing list -- python-ideas@python.org <mailto:python-ideas@python.org> To unsubscribe send an email to python-ideas-leave@python.org <mailto: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/YKLNQX... 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/PQSJ6P... Code of Conduct: http://python.org/psf/codeofconduct/
`yield from` is a case where two keywords are used together to do something new, but they're both keywords independently of each other. If `a` can be variable or a keyword, we'd have to decide when `x is a y` is using `a` as a keyword and when it's using it as a variable. I don't think introducing that possibility is worth the effort. On Fri, May 1, 2020 at 2:13 PM Soni L. <fakedme+py@gmail.com> wrote:
On 2020-05-01 2:46 p.m., Steele Farnsworth wrote:
So this would make `a` a new keyword. I don't think that could be added into python 4 at the earliest because it would immediately break all code for which `a` is a variable name.
we could have keyphrases instead of keywords, tbh.
I can appreciate wanting to make simple operations easy to read, though I think this relies too much on understanding English and wouldn't be intuitive for people who aren't English speaking. I am native English speaking so I wouldn't know for sure, but I think accepting that "or" is the same as "||" is an easier jump to make than "x is a y" being a construct for indicating that x belongs to the y class.
If you need this English-style syntax, I believe `type(x) is y` is guaranteed to be True if x is exactly of the y type and not one of its super classes.
On Fri, May 1, 2020, 1:27 PM gbs--- via Python-ideas < python-ideas@python.org> wrote:
In cases where it makes sense to do explicit type checking (with ABCs or whatever), I really detest the look of the isinstance() function.
if isinstance(thing, Fruit) and not isinstance(thing, Apple):
Yucky.
What I really want to write is:
if thing is a Fruit and thing is not an Apple:
and after thinking about it on and off for a while I wonder if it might indeed be possible to teach the parser to handle that in a way that eliminates almost all possible ambiguity with the regular "is", including perhaps 100% of all existing standard library code and almost all user code?
Maybe this has been considered at some point in the past? The "is [not] a|an" proposal would at least be a strong contender for "hardest thing to search for on the internet" lol.
Thanks!
Gavin _______________________________________________ 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/YKLNQX... 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.orghttps://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/PQSJ6P... 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/JFSNV7... Code of Conduct: http://python.org/psf/codeofconduct/
On May 1, 2020, at 10:27, gbs--- via Python-ideas <python-ideas@python.org> wrote:
In cases where it makes sense to do explicit type checking (with ABCs or whatever), I really detest the look of the isinstance() function.
if isinstance(thing, Fruit) and not isinstance(thing, Apple):
Yucky.
I think it’s intentional that it’s a little yucky. It makes you think “could I be using duck typing or overridden methods here instead of type switching?” Sure, sometimes the answer is, “No, I can’t,” which is why ABCs were added. But if you’re using them so often that you get annoyed by the ugliness, then maybe you’re using an antipattern—or, if not, there’s a good chance you’re doing something that’s perfectly valid but unusual for Python, so the language just isn’t going to cater to you. Maybe Python leans a little too far toward discouraging type checks, because there was so much resistance to the very idea of ABCs until people got used to them. But if so, I suspect you’ll need a solid example of realistic code that should look better, and can’t be reasonably redesigned, to convince people, not just showing that isinstance is about as ugly as it was designed to be.
What I really want to write is:
if thing is a Fruit and thing is not an Apple:
and after thinking about it on and off for a while I wonder if it might indeed be possible to teach the parser to handle that in a way that eliminates almost all possible ambiguity with the regular "is", including perhaps 100% of all existing standard library code and almost all user code?
Possible? Yes, at least with the new parser coming from PEP 617. But that doesn’t mean it’s a good idea. You certainly can’t make a and an into keywords, because lots of people have variables named a. You can’t even make them into “conditional keywords”, that only have a special meaning after “is” and “is not”—besides all the usual negatives of conditional keywords, it won’t work, because “b is a” is already perfectly reasonable code today. So you’d need to add some kind of backtracking: they’re conditional keywords only if they follow “is” or “is not” and are followed by a valid expression. Which is more complicated (and less efficient) to parse. Some third-party parser tools might even have to be completely rewritten, or at least to add special case hacks for this. And, more importantly, the more context it takes to parse things (or the more special cases you have to learn and memorize), the harder the language’s syntax is to internalize. The fact that Python is (almost) an LL(1) language makes it pretty easy to get most of syntax for the subset that you use firmly into your head. Every special case makes that less true, which means more cases where you get confused by a SyntaxError in your code or about what someone else’s code means, and means it’s harder to manually work through the parse when you do get stumped like that and you resort to shotgun-debugging antics instead. For a practical example, look at some languages that are actually designed to be executable English rather than executable pseudocode, like AppleScript or Inform. The fact that “bring every window of the first app to the foreground” reads like a normal English sentence is pretty cool, but the fact that “bring the first window of every app to the foreground” gives you an error message about not knowing what the every is, and the only way to rewrite it is “tell every app to bring the first window of it to the foreground”, severely dampens the coolness factor.
Maybe this has been considered at some point in the past? The "is [not] a|an" proposal would at least be a strong contender for "hardest thing to search for on the internet" lol.
That will also make it hard to search for when you see some code you don’t understand and need to search for help, won’t it? A search for “isinstance” (even without including Python) brings me the docs page, some tutorials and blogs, and some StackOverflow questions; what’s a search for “is a” or even “Python is a” going to get me? Maybe you could get more mileage out of going halfway there, with an operator named isa. Other languages use that spelling for related things (in Perl it’s exactly the operator you want; in ObjC it’s a property on the instance but it’s still about types), and people often use “isa” or “is-a” as a technical term in comp sci. if thing isa Fruit and thing not isa Apple: That’s still pretty readable, and easy to parse. But it still breaks backward compatibility, because people do have code that uses “isa” as a normal identifier. (For one thing, it’s how you access the isa attribute of an ObjC object in PyObjC.)
Hi Gavin, You have Reply To set to your personal email address instead of allowing replies to go to the list for everyone to contribute to the discussion. Was that intentional? On Fri, May 01, 2020 at 04:53:31PM -0000, gbs--- via Python-ideas wrote:
In cases where it makes sense to do explicit type checking (with ABCs or whatever), I really detest the look of the isinstance() function.
Is it just the `isinstance` function you detest, or all functions? If it's just `isinstance`, then you can alias it: is_a = isinstance if is_a(thing, Fruit): # yuck this is worse but if it is all functions, then I think you have no choice but to either live with it or shift languages, because the syntax for functions is too deeply baked into Python to change now. [...]
What I really want to write is:
if thing is a Fruit and thing is not an Apple:
and after thinking about it on and off for a while I wonder if it might indeed be possible to teach the parser to handle that in a way that eliminates almost all possible ambiguity with the regular "is", including perhaps 100% of all existing standard library code and almost all user code?
Whether it is possible is only half the question. Whether it is desirable is the other half. My first language was Apple's Hypertalk back in the 1990s, which used a very English-like syntax where things like "is a" would have been right at home. For example: if there is a file "myfile.pct" then ... Functions could be written in either traditional parenthesized format, or English-like prefix operator syntax: root = sqrt(value) put the sqrt of value into root It's been two decades since I've last written a line of Hypertalk code and I still miss it :-) so I'm definitely sympathetic to your request. But I fear that few others will be. If we wanted this new operator, I think it should combine isinstance and issubclass: obj is a T should be equivalent to: issubclass(obj, T) if isinstance(obj, type) else isinstance(obj, T) and T is a type or tuple of types. The rules in English for when to use "a" versus "an" depend on the *sound* of the following word, not the initial letter. Blindly applying the rule "an before vowels otherwise a" is wrong: an uncle # correct an unicorn # wrong so I propose that the interpreter allow either, and we leave it to the programmer and/or linters to enforce good English grammar: obj is an int obj is an float # accepted by interpreter obj is a int # also accepted by interpreter In other words, the "is-a" operators would become: is a[n] is not a[n] The above is the easy part. The hard part is justifying why this should become an operator.
Maybe this has been considered at some point in the past? The "is [not] a|an" proposal would at least be a strong contender for "hardest thing to search for on the internet" lol.
Indeed :-) But for what it's worth, I don't remember coming across this myself. -- Steven
On May 1, 2020, at 15:35, Steven D'Aprano <steve@pearwood.info> wrote:
but if it is all functions, then I think you have no choice but to either live with it or shift languages, because the syntax for functions is too deeply baked into Python to change now.
Actually, I’m pretty sure Python could add infix calling without complicating the grammar much, or breaking backward compatibility at all. I don’t think it *should*, but maybe others would disagree. The most obvious way to do it is borrowing straight out of Haskell, so this: x `spam` y … compiles to exactly the same code as this: spam(x, y) That should be a very easy change to the grammar and no change at all to the later stages of compiling, so it’s about as simple as any new syntax could be. It doesn’t get in the way of anything else to the parser—and, more importantly, I don’t think it’s confusable as meaning something else to humans. (Of course it would be one extra thing to learn, like any syntax change.) Maybe something like $ instead of backticks is better for people with gritty monitors, but no point bikeshedding that (or the precedence) unless the basic idea is sound. Anyway, it’s up to the user to decide which binary functions to infix and which to call normally, which sounds like a consenting-adults issue, but… does it _ever_ look Pythonic? For this particular use case: isa = isinstance thing `isa` Fruit and not thing `isa` Apple … honestly, the lack of any parens here makes it seem harder to read, even if it is a bit closer to English. Here’s the best use cases I can come up with: xs `cross` ys array([[0,1], [1,1]]) `matrix_power` n prices `round` 2 These are all things I have written infix in Haskell, and can’t in Python/NumPy, so you’d think I’d like the improvement… but if I can’t have real operators, I think I want dot-syntax methods with parens instead in Python: prices.round(2) And outside of NumPy, the examples seem to just get worse: with open(path, 'w') as f: obj `json.dump` f Of course maybe I’m just failing to imagine good examples.
I guess I need to remind folks about the reasons why infix operators are useful. It's not (primarily) about the lack of parentheses or the resemblance to English (oh horror). It's about the *associative property*. For example, it's a good idea to use a binary operator for string concatenation, since (s1 `concat` s2) `concat` s3 produces the same result as s1 `concat` (s2 `concat` s3), so it's reasonable to write it as s1 `concat` s2 `concat` s3 rather than as concat(s1, concat(s2, s3)) or concat(concat(s1, s2), s3). And sure, you could improve by having a varargs concat() function (which we do: "".join(s1, s2, s3)), but that only goes so far. But for a binary operation that doesn't have this useful (and rare!) property, spelling it as an infix operator doesn't buy you much. This would explain why `json.dump` makes a poor operator (and probably `round` too, though I honestly have no idea what it does). There's also the benefit of being able to combine *different* operators without having to use parentheses (like 2*x + 3*y), but that depends strongly on whether people can remember the priority of the various operators. (Python, following C, takes this a bit too far, and I have to look up the associativity of shift and bitwise operators.) For newly minted operators like `round` this benefit goes away -- presumably there's only one priority for that form, and it probably is lower than all other operators. Finally there's the benefit of matching common mathematical operators that are traditionally spelled as infix operators -- but most people know only a handful of these, and some of those aren't even associative (e.g. subtraction of vector cross product). Nevertheless, it's nice to be able to follow the mathematical tradition, as long as the typical programmer is familiar with that tradition. (Maybe there's a traditional "round" operator in some field of math commonly practiced by numpy users that I've never heard of?) --Guido On Fri, May 1, 2020 at 7:42 PM Andrew Barnert via Python-ideas < python-ideas@python.org> wrote:
On May 1, 2020, at 15:35, Steven D'Aprano <steve@pearwood.info> wrote:
but if it is all functions, then I think you have no choice but to either live with it or shift languages, because the syntax for functions is too deeply baked into Python to change now.
Actually, I’m pretty sure Python could add infix calling without complicating the grammar much, or breaking backward compatibility at all. I don’t think it *should*, but maybe others would disagree.
The most obvious way to do it is borrowing straight out of Haskell, so this:
x `spam` y
… compiles to exactly the same code as this:
spam(x, y)
That should be a very easy change to the grammar and no change at all to the later stages of compiling, so it’s about as simple as any new syntax could be. It doesn’t get in the way of anything else to the parser—and, more importantly, I don’t think it’s confusable as meaning something else to humans. (Of course it would be one extra thing to learn, like any syntax change.) Maybe something like $ instead of backticks is better for people with gritty monitors, but no point bikeshedding that (or the precedence) unless the basic idea is sound.
Anyway, it’s up to the user to decide which binary functions to infix and which to call normally, which sounds like a consenting-adults issue, but… does it _ever_ look Pythonic?
For this particular use case:
isa = isinstance
thing `isa` Fruit and not thing `isa` Apple
… honestly, the lack of any parens here makes it seem harder to read, even if it is a bit closer to English.
Here’s the best use cases I can come up with:
xs `cross` ys array([[0,1], [1,1]]) `matrix_power` n prices `round` 2
These are all things I have written infix in Haskell, and can’t in Python/NumPy, so you’d think I’d like the improvement… but if I can’t have real operators, I think I want dot-syntax methods with parens instead in Python:
prices.round(2)
And outside of NumPy, the examples seem to just get worse:
with open(path, 'w') as f: obj `json.dump` f
Of course maybe I’m just failing to imagine good examples. _______________________________________________ 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/AQPPHK... Code of Conduct: http://python.org/psf/codeofconduct/
-- --Guido van Rossum (python.org/~guido) *Pronouns: he/him **(why is my pronoun here?)* <http://feministing.com/2015/02/03/how-using-they-as-a-singular-pronoun-can-c...>
On Fri, May 01, 2020 at 07:41:57PM -0700, Andrew Barnert wrote:
The most obvious way to do it is borrowing straight out of Haskell, so this:
x `spam` y
… compiles to exactly the same code as this:
spam(x, y)
I really, really want to like that syntax, but I can't. The backticks get in the way. It's not that I don't like backticks. I do. But to the degree that "infix operators" are words: x is y rather than symbols, the backticks get in the way of it looking like a word: x `is` y Even though they're only grit on Tim's monitor *wink* nevertheless they stand out too much for my liking. (Maybe I wouldn't think so if my native language used more accents?) So I'm afraid that I can't get past the idea that for a good looking, attractive syntax, you can either go whole-hog for Hypertalk-like natural(-ish) language syntax: the number of words of line 1 of text or functional notation: len(words(lines(text)[0])) but cramming them into the same language with backticks or dollar signs or some other sygil might be technically possibly but aesthetically ugly. (Likewise I like Forth-like RPN code, but I don't think trying to cram it into Python would look good.) [...]
For this particular use case:
isa = isinstance thing `isa` Fruit and not thing `isa` Apple
… honestly, the lack of any parens here makes it seem harder to read, even if it is a bit closer to English.
Do you think the same about this? thing is None and not obj is None If not, perhaps its just familiarity. Or the backticks getting in the way for you too :-) -- Steven
On the subject of custom infix operators, there are at least two packages on PyPI that allow you to do this already: https://pypi.org/project/funcoperators/ https://pypi.org/project/infix/ On Sat, May 2, 2020 at 12:51 AM Steven D'Aprano <steve@pearwood.info> wrote:
On Fri, May 01, 2020 at 07:41:57PM -0700, Andrew Barnert wrote:
The most obvious way to do it is borrowing straight out of Haskell, so this:
x `spam` y
… compiles to exactly the same code as this:
spam(x, y)
I really, really want to like that syntax, but I can't. The backticks get in the way. It's not that I don't like backticks. I do. But to the degree that "infix operators" are words:
x is y
rather than symbols, the backticks get in the way of it looking like a word:
x `is` y
Even though they're only grit on Tim's monitor *wink* nevertheless they stand out too much for my liking. (Maybe I wouldn't think so if my native language used more accents?)
So I'm afraid that I can't get past the idea that for a good looking, attractive syntax, you can either go whole-hog for Hypertalk-like natural(-ish) language syntax:
the number of words of line 1 of text
or functional notation:
len(words(lines(text)[0]))
but cramming them into the same language with backticks or dollar signs or some other sygil might be technically possibly but aesthetically ugly.
(Likewise I like Forth-like RPN code, but I don't think trying to cram it into Python would look good.)
[...]
For this particular use case:
isa = isinstance thing `isa` Fruit and not thing `isa` Apple
… honestly, the lack of any parens here makes it seem harder to read, even if it is a bit closer to English.
Do you think the same about this?
thing is None and not obj is None
If not, perhaps its just familiarity. Or the backticks getting in the way for you too :-)
-- 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/YMYFH3... Code of Conduct: http://python.org/psf/codeofconduct/
participants (7)
-
Andrew Barnert
-
gbs@me.com
-
Guido van Rossum
-
Jonathan Goble
-
Soni L.
-
Steele Farnsworth
-
Steven D'Aprano