[Python-ideas] Re: Conditional with statements

2021-02-14 Thread David Mertz
On Sun, Feb 14, 2021, 5:46 PM Steven D'Aprano  wrote:

> I'm curious why you say that if and with are "almost" orthogonal concepts?
> They seem completely orthogonal to me. You can mix and match them in
> literally every combination:
>

I mean in a conceptual sense, not as a matter of Python grammar.

Grammatically, I can nest 'for' and 'while' inside each other in any
combination, but they do "kinda the same thing." I genuinely need to decide
sometimes whether to use one or the other for greater clarity in a certain
bit of code. I never need to make that decision between 'if' and 'with'.

Python wouldn't be that much worse a language if it dropped one of 'for'
and 'while'. Of course I don't advocate such, but it's easy to write:

for _ in itertools.repeat(None):
if something: break

Or alternatively,

while True:
loopvar = next(stuff)

The only sense in which I grant "almost" to with/if is that *occasionally*
I want to perform an if test on a context object right after it's bound. In
that uncommon case, they are slightly non-orthogonal. But the same is true
of for/if and other combos.

>
___
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@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/2Z4C46BBJD4XUBQQGBJFXO4AYU5EHVFG/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: Arrow functions polyfill

2021-02-14 Thread Chris Angelico
On Mon, Feb 15, 2021 at 5:28 PM Steven D'Aprano  wrote:
> In the first case, => will forever be fighting against the much stronger
> memory trace of >= (I think we can agree that comparisons will be more
> common than anonymous functions). People's muscle-memory will type >=
> when they want the arrow; people will wrongly read => as a comparison.
>

I've worked a lot with JS's arrow functions, and I've taught them to a
good number of students, and this is basically a non-issue.

In JS, the need for arrow functions is a lot stronger, as they
actually have different semantics to "function functions" (for want of
a better word). In Python, the need isn't as great, but there would be
some minor value in this syntax.

Overall I'm +0.1 on either => or ->, and have absolutely no push
either way which one is chosen.

ChrisA
___
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@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/IFAWXQF6FH3HLBHEWTSC4KTETTST2NMC/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: Arrow functions polyfill

2021-02-14 Thread Steven D'Aprano
On Sun, Feb 14, 2021 at 01:31:29AM -0500, Random832 wrote:

> > http://www.rosettacode.org/wiki/Function_definition
> 
> That page doesn't really do well at explaining lambda expressions 
> specifically, omitting it for some languages that definitely have them 
> [such as Dart].

It's a community site. I'm sure we could fix that if we wanted to and 
had sufficient Round Tuits.


> https://en.wikipedia.org/wiki/Anonymous_function may be better.

May be or is? Either way, thanks for the link.


> I don't really buy that anyone wouldn't understand what passing 
> "x=>x+1" as an argument means if they understand the concept of 
> first-class functions generally.

That's not the argument being made.

The argument is that people will confuse -> and => and be unsure of the 
difference, and confuse => with >= comparison operator.

I think it is disingenuous to deny that second one when this thread 
included a good example of a highly experienced, motivated Python 
programmer mixing up the two symbol. If Paul can do it, we all can.


> I still think arrows are the clear winner. I think they're intuitive, 
> and I think that's *why* C# chose them and why other languages like 
> Javascript copy them. It wouldn't be the first syntactic feature we'd 
> have copied from C#.

Out of curiosity, which other features are those?

I don't think that the argument is specifically about arrows. (Except to 
the degree that we already have a way to spell anonymous functions, and 
it isn't clear why we need a second way just to save a handful of 
characters:

lambda a, b, c: a+b*c
(a, b, c) -> a+b*c

The argument is between the arrow that can be confused with a 
comparison, versus the arrow that is already used for a closely related 
concept.

In the first case, => will forever be fighting against the much stronger 
memory trace of >= (I think we can agree that comparisons will be more 
common than anonymous functions). People's muscle-memory will type >= 
when they want the arrow; people will wrongly read => as a comparison. 

And people will ask what the difference is between => and -> the arrow 
we already have.


> > - how many people coming to Python will be familiar with Javascript as 
> >   opposed to R, Julia, Maple, etc, or no language at all?
> 
> I don't really understand why you're bringing up R/Julia/Maple 
> specifically. Are you advocating for ->? 

Um, yes. Wasn't it clear enough?



> I have no particular 
> objection to that, but I don't think the difference between two 
> slightly different looking arrows [one used in C#, Javascript, Scala, 
> and D; the other used in Java, Kotlin, Julia, R, and Maple] is 
> particularly difficult. I think either one is just as good as the 
> other in terms of the meaning being intuitive when reading code.

In isolation, sure. But Python already has a forward arrow -> and 
something that looks like a backward arrow <= but isn't.


> > - given how many other things they will have to learn that is different, 
> >   is one comparatively rarely used feature more that much of a burden?
> 
> It's not about being the same to make it easier for people coming from 
> a particular language. It's being the same because C# (and Javascript) 
> gets it right, and we should get it right. *semi-wink*

Okay, let's do a shoot-out: if we were designing the syntax in isolation 
(no other languages exist; everyone uses Python) what are the objective 
advantages and disadvantages of each arrow spelling?

* Clearly both -> and => look like arrows. Tie.

* Both require the same number of keypresses. Tie.

* Similar things should look similar. -> is already used for 
  **return annotations** which is semantically related to 
  **return values** so the use of -> for both concepts strengthens the 
  association of the arrow symbol with returning stuff.

* Things which look confusingly similar cause confusion. => looks 
  confusingly similar to -> which will lead to people mixing up the two 
  arrows and asking "what's the difference between ...?"

* Things which are dissimilar should look dissimilar. => is very 
  different from >= and <= but they look similar.

Every advantage of => is equally shared with -> but => has two 
disadvantages, and no advantages, compared to ->.

So if we're tallying pros - cons for each symbol, I make that:

=> 2 pros - 2 cons = 0

-> 3 pros - 0 cons = 3

I think this is a slam dunk. If you disagree, can you give some 
objective pluses for the => symbol that doesn't rely on familiarity with 
other languages?



-- 
Steve
___
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@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/XHUU7FMIFTCHQLJGEOP2WVRPGUMGY5NS/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: Conditional with statements

2021-02-14 Thread Christopher Barker
Getting OT here -- you've been warned.

On Sun, Feb 14, 2021 at 2:10 AM Rob Cliffe 
wrote:

> You've broken a number of "rules" code code formatting there ;-)
>
> Thanks for the quotation marks.  Indeed, PEP 8 provides guidelines, not
> diktats.
>
> A big one is aligning things vertically, which, as a rule, I like. but
> this example does really push things out away from each other, so I'm not
> so sure.
>
> It's written to suit my editor.  I'm with Brendan: restricting the whole
> world to 80 chars per line is like insisting the whole world program in
> COBOL.
>

I agree about the 80 char limit -- personally using usually 90 or 95.

But I do think you need to consider not just your editor -- if anyone else
is going to read your code.

But in your example, it not only has long lines, but by lining up the stuff
after the colon -- there is a LOT of info way over on the right, which I'm
not so sure about.

> Just for fun, here it is after being run through Black (which I don't
> usually use ) -- but I think it looks better that way.
>
> Also -- my first thought looking at that was that it could really
> benefit from the pattern matching :-)
>
> Yes IMHO it would be a slight improvement.  But AFAIU pattern matching is
> not available yet.
>

no, it's not. That was a note for me in a way -- I'm a bit of a skeptic
about pattern matching, so this is a good example use case.


> And my second thought was that there could be a whole other pattern used
> here -- I usually find long chained elifs can be better expressed as a dict
> selection, or subclassing, or ...
>
> I cannot imagine how a dictionary, much less a subclass (of what)?  could
> have any relevance here.  I'd be interested if you could elucidate.
>

Again, I don't know what the rest of your code looks like, so maybe none of
these would work well, but:

for using a dict, you could set it up something like:

ch_proc_dict = {"B": self.ToggleBackgroundColour,
"C": self.ChangeCommonChars,
"D": self.DeleteArea,
...
}
then:

if process_dict[ch](event):
return

you also have other checks in there, so those would have to be moved into
the functions in the dict, maybe with wrappers (or not -- depends on where
you store some of that state data.

as for subclassing, that's a very different pattern that probably doesn't
apply here now that I think about it:

This looks to me like wxPython code (or the like).  for wx.lib.floatcanvas,
I don't have keyboard accelerators, but I do have "GUI Modes"  classes:
Depending on what Mode is set at the moment, each event gets mapped to
different actions, so you might have different handling of the character
hit depending on what object is selected:

object_selected.process_keystroke(ch)

Of course, you'd need this kind of "switch" construct in the object class
anyway. Unless you wanted to get really wordy, and have:

def process_A(self..)
...
def process_B(self...)
...

you could be a bit saved in Python:

getattr(selected_object, "process" + ch)(event)

Anyway, as I say -- pretty darn off topic, but those are two of the three
ways that I think "switch -- case" can be spelled in Python.

-Chris B


 if ch == "B":

self.ToggleBackgroundColour(event)
> elif ch == "C":
> self.ChangeCommonChars(event)
> return
> elif ch == "D" and len(Areas) > 1:
> self.DeleteArea(event)
> return
> elif ch == "F" and __debug__:
> self.Info(event)
> return
> elif ch == "I":
> self.ChangeImagesToScroll(event)
> return
> elif ch == "J" and self.NUMBER_OF_IMAGES == 1:
> self.ChangeJustification(event)
> return
> elif ch == "L":
> self.ToggleShowLabels(event)
> elif ch == "M" and MaxNumberOfImages > 1:
> self.ChangeNumberOfImages(event)
> elif ch == "N" and CanZapImage:
> self.Rename(event)
> elif ch == "R" and not (area.Dynamic | area.IsTour):
> self.ToggleRandom(event, 1)
> elif ch == "S":
> self.ToggleSets(event, 1)
> elif ch == "T":
> self.ChangeTimer(event)
> return
> elif ch == "U" and not (area.Dynamic | area.Random):
> self.ToggleIsTour(event, 1)
> elif ch == "V" and OnAnImage:
> self.WindowsPhotoViewer(event)
> return
> elif ch == "W":
> self.ToggleWrap(event, 1)
> elif ch == "Y" and not (area.Random | area.IsTour):
> self.ToggleDynamic(event, 1)
> elif ch == "Z" and CanZapImage:
> self.Zap(event)
> elif ch == "A" and not (area.Dynamic | area.IsTour):
> self.ToggleRandom(event, 1)
> # Alt-R doesn't always work for some reason, so we give Alt-A as an
> alternative
> else:
> event.Skip()
>
> I'm well aware that if you apply PEP 8 guidelines strictly it would look
> like the above.  But is this supposed to be an improvement?
>

I did it to compare and decide -- I'm ambivalent.


>   My original was a clear, tabular layout making the code structure
> completely clear, the vertical alignment *highlighting where different
> cases are treated differently and where 

[Python-ideas] Re: Arrow functions polyfill

2021-02-14 Thread Brendan Barnwell

On 2021-02-14 00:54, Paul Sokolovsky wrote:

There're 2 things about that from an experienced JavaScript-hater (but
a pragmatic guy otherwise):

1. We aren't talking about all of JavaScript, but a recent features
added to JS.
2. JS has real money being poured into it, and no longer designed on
two-week vacations, when nobody looks. On the JS committees/proposal
author lists are guys who have publications in serious programming
language design matters and "grown up" languages, like proverbial
Haskell. And they peer-review each other. So, with due understanding of
the baseline https://en.wikipedia.org/wiki/Design_by_committee process,
some recent features in JS are well-designed.


	Maybe, but the problem is that they're cripplingly constrained by their 
unwillingness to ever remove features or change old behavior.  So to the 
extent that features are "well-designed" they're only well-designed to 
fit into the crappy design that already exists.


--
Brendan Barnwell
"Do not follow where the path may lead.  Go, instead, where there is no 
path, and leave a trail."

   --author unknown
___
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@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/G3NKW4VPORWD33CKWUUNNH73VT6CSR7W/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: Conditional with statements

2021-02-14 Thread Steven D'Aprano
On Mon, Feb 08, 2021 at 02:45:57AM -0500, David Mertz wrote:

> I don't like the actual proposal. It weirdly combines almost orthogonal
> concepts into the same block statement.

I'm curious why you say that if and with are "almost" orthogonal 
concepts? They seem completely orthogonal to me. You can mix and match 
them in literally every combination:

* if alone

* with alone

* if block inside the with block

* with block inside the if block

* with block inside the else block

etc. Why single out one special case?

But generalising this is worse. We don't want Perlish one liners.

# where the process ends
if condition: for x in items: with thingy as cm: if predicate: while cond: 
for y in stuff: do_something()



-- 
Steve
___
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@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/VZ73FUMCS5V7T5Y5IS7NXAUXMEMOMDJS/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Pattern-Matching for functions

2021-02-14 Thread Abdulla Al Kathiri
In some functional programming languages, they can pattern match a function 
based on its parameters. Similar to function overloading. Will Python Pattern 
Matching do something similar to functions?

If calling a function doesn't match any of the cases and catch-all case is not 
present, then some sort of new or exisiting Exception needs to be raised. 

Type annotations can be used (for the parameters, they may be redundant, but 
for the return, they can be useful). The Return annotation comes right after 
the guard. 

See theortical example below.

class Point:
def __init__(self, pos):
self.pos = pos
def write(self, msg):
return f"writing {msg}"

match def f:
case (float(x) | int(x), float(y) | int(y)) if x > 0 -> int:
return round(x + y)
# f(3.4, 7) => 10

case (int(x) | float(x)):
return round(2 * x)
# f(8) => 16

case (0):
return 0
# f(0) => 0

case (0, 0):
return "Origin"
# f(0, 0) => "Origin"

case ([int(x) | float(x), int(y) | float(y)], int(z) | float(z)):
return x + y + z
# f((5, 2.5), 2.5) => 10

case (
(Point(pos=(int(x), int(y as point, 
*_, 
message=str(msg), 
**_,
) if x > 0 and y > 0:
txt = point.write(msg)
res = x + y
return res, txt
# point = Point([1, 9])
# f(point, message="Hello") => 10, "writing Hello"

case (*_, **_):
return "Catch_All"
## which can be shortened to...
case _:
return "Catch_All"
#f(1, 3, 4, 5) => “Catch_All"



___
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@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/3M4PDXEBQM2OROTFOZ6EZDFTZK2HM5NN/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: Pattern Matching -- Removing Name Binding from Partial Matching

2021-02-14 Thread Guido van Rossum
I should add that I accidentally left out a word. It should be “... liable
to *overwrite* any or all names ...”

On Sun, Feb 14, 2021 at 12:10 Abdulla Al Kathiri <
alkathiri.abdu...@gmail.com> wrote:

> That makes sense. As Guido mentioned, this is similar to reusing a
> variable in a for-loop. You do it at your own risk. Ok consider me
> convinced. I will use the following sentence to explain name binding in
> partial matching:
> *“Match statements are liable to any or all names bound in any of the
> patterns used, and your code is incorrect if you aren't prepared for that."*
>
>
> On 14 Feb 2021, at 7:20 PM, Chris Angelico  wrote:
>
> On Sun, Feb 14, 2021 at 11:26 PM Abdulla Al Kathiri
>  wrote:
>
>
> My idea was that in the case of partial matching or full matching without
> passing the guard, the binding names has some sort of self destruction and
> return to the previous state. Using different variable names would resolve
> the issue and if I want to modify the global variables, I could choose to
> do so in the case block after the case succeeded. At least, this way, it
> would be more explicit, conveying the person intention (or forgetting if
> the original global value was later needed). I saw many people online
> talking about this the last couple of days so I thought I would bring it up
> here.  Any other syntax variant could be used to achieve the same thing.
>
>
> It's not about syntax. Python doesn't have an idea of "self
> destruction and return to the previous state". The nearest equivalent
> is a very special case at the end of an exception handler, where after
> "except Exception as e:" you'll get an implicit "e = None; del e" to
> prevent a refloop. That's not a return to the previous state, that's a
> conscious clearing of one reference.
>
> If this "unwinding" were desired, the best way would be to simply make
> it a permanent part of the match semantics - no syntax for selecting
> which behaviour you want. There's no backward compatibility to be
> maintained (yet). But that would be inconsistent with the rest of
> Python, where things happen step by step, and if something breaks,
> everything prior to it has happened.
>
> ChrisA
> ___
> Python-ideas mailing list -- python-ideas@python.org
> To unsubscribe send an email to python-ideas-le...@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/5K65WY7B6O7EO5ZKWZZCS3OYV2HCIBQJ/
> Code of Conduct: http://python.org/psf/codeofconduct/
>
>
> ___
> Python-ideas mailing list -- python-ideas@python.org
> To unsubscribe send an email to python-ideas-le...@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/LQWGSE7DYQHXQQCVJDDRXROZ7WHYDHQQ/
> Code of Conduct: http://python.org/psf/codeofconduct/
>
-- 
--Guido (mobile)
___
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@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/CXLTVIRD3BWQIQTQMKQXR7NWJ7Y6I6SI/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: Pattern Matching -- Removing Name Binding from Partial Matching

2021-02-14 Thread Abdulla Al Kathiri
That makes sense. As Guido mentioned, this is similar to reusing a variable in 
a for-loop. You do it at your own risk. Ok consider me convinced. I will use 
the following sentence to explain name binding in partial matching:
“Match statements are liable to any or all names bound in any of the patterns 
used, and your code is incorrect if you aren't prepared for that."

> On 14 Feb 2021, at 7:20 PM, Chris Angelico  wrote:
> 
> On Sun, Feb 14, 2021 at 11:26 PM Abdulla Al Kathiri
> mailto:alkathiri.abdu...@gmail.com>> wrote:
>> 
>> My idea was that in the case of partial matching or full matching without 
>> passing the guard, the binding names has some sort of self destruction and 
>> return to the previous state. Using different variable names would resolve 
>> the issue and if I want to modify the global variables, I could choose to do 
>> so in the case block after the case succeeded. At least, this way, it would 
>> be more explicit, conveying the person intention (or forgetting if the 
>> original global value was later needed). I saw many people online talking 
>> about this the last couple of days so I thought I would bring it up here.  
>> Any other syntax variant could be used to achieve the same thing.
>> 
> 
> It's not about syntax. Python doesn't have an idea of "self
> destruction and return to the previous state". The nearest equivalent
> is a very special case at the end of an exception handler, where after
> "except Exception as e:" you'll get an implicit "e = None; del e" to
> prevent a refloop. That's not a return to the previous state, that's a
> conscious clearing of one reference.
> 
> If this "unwinding" were desired, the best way would be to simply make
> it a permanent part of the match semantics - no syntax for selecting
> which behaviour you want. There's no backward compatibility to be
> maintained (yet). But that would be inconsistent with the rest of
> Python, where things happen step by step, and if something breaks,
> everything prior to it has happened.
> 
> ChrisA
> ___
> Python-ideas mailing list -- python-ideas@python.org 
> 
> To unsubscribe send an email to python-ideas-le...@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/5K65WY7B6O7EO5ZKWZZCS3OYV2HCIBQJ/
>  
> 
> Code of Conduct: http://python.org/psf/codeofconduct/ 
> 
___
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@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/LQWGSE7DYQHXQQCVJDDRXROZ7WHYDHQQ/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: Alternate lambda syntax

2021-02-14 Thread Christopher Barker
On Sun, Feb 14, 2021 at 4:26 AM Serhiy Storchaka 
wrote:

> Lambda is a questionable feature at all. With support of comprehensions,
> local functions, the operator and functools modules there are not many
> use cases for lambda expression. They are supported, well, but it is not
> significant part of the language.
>

Thank you -- I'm not quite sure they are "questionable", but they do have
limited use in the language, and far less use then they did back in the
early days of Python. In fact, most of the uses I've seen of lambda in
recent code (particularly from newbies) is totally unnecessary.

If the only thing this proposal is about is a way to create small anonymous
functions without using the keyword "lambda" -- it is pretty darn pointless.

And frankly, this compact notation is a lot harder (for me at least) to
parse at a glance -- "lambda" may be a strange and confusing word for
newbies, but it's easy to look up, and it's really obvious that *something*
is going on there. Whereas parentheses are used all over the place, and are
often optional. And more "line noise"-like symbols like => isn't really
going to help.

In fact, I've only written a smattering of C, but it still requires some
extra thinking to identify where a function is being defined -- a keyword
(like def) would be so much more clear to me.

Final point:

Python has been around a long time, there's a lot of code already written
-- any changes to syntax should only be ones that add real functionality or
expressiveness -- a slightly-easier-to-write (and maybe read) anonymous
function syntax is nowhere near that threshold.

-Chris B

-- 
Christopher Barker, PhD (Chris)

Python Language Consulting
  - Teaching
  - Scientific Software Development
  - Desktop GUI and Web Development
  - wxPython, numpy, scipy, Cython
___
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@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/U4P4CX7Q2RTV6BSPMWY2TD7LA53EPSYF/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: Conditional with statements

2021-02-14 Thread Rob Cliffe via Python-ideas



On 14/02/2021 02:23, Christopher Barker wrote:

Thanks Rob.

You've broken a number of "rules" code code formatting there ;-)
Thanks for the quotation marks.  Indeed, PEP 8 provides guidelines, not 
diktats.
A big one is aligning things vertically, which, as a rule, I like. but 
this example does really push things out away from each other, so I'm 
not so sure.


I found that the original looked like heck when I first opened it in 
my editor -- once I made the window wide enough it was better, but 
still pretty stretched out.
It's written to suit my editor.  I'm with Brendan: restricting the whole 
world to 80 chars per line is like insisting the whole world program in 
COBOL.


Just for fun, here it is after being run through Black (which I don't 
usually use ) -- but I think it looks better that way.


Also -- my first thought looking at that was that it could really 
benefit from the pattern matching :-)
Yes IMHO it would be a slight improvement.  But AFAIU pattern matching 
is not available yet.


And my second thought was that there could be a whole other pattern 
used here -- I usually find long chained elifs can be better expressed 
as a dict selection, or subclassing, or ...
I cannot imagine how a dictionary, much less a subclass (of what)? could 
have any relevance here.  I'd be interested if you could elucidate.


But not seeing the rest of the application, maybe maybe not in this case.

if ch == "B":
    self.ToggleBackgroundColour(event)
elif ch == "C":
    self.ChangeCommonChars(event)
    return
elif ch == "D" and len(Areas) > 1:
    self.DeleteArea(event)
    return
elif ch == "F" and __debug__:
    self.Info(event)
    return
elif ch == "I":
    self.ChangeImagesToScroll(event)
    return
elif ch == "J" and self.NUMBER_OF_IMAGES == 1:
    self.ChangeJustification(event)
    return
elif ch == "L":
    self.ToggleShowLabels(event)
elif ch == "M" and MaxNumberOfImages > 1:
    self.ChangeNumberOfImages(event)
elif ch == "N" and CanZapImage:
    self.Rename(event)
elif ch == "R" and not (area.Dynamic | area.IsTour):
    self.ToggleRandom(event, 1)
elif ch == "S":
    self.ToggleSets(event, 1)
elif ch == "T":
    self.ChangeTimer(event)
    return
elif ch == "U" and not (area.Dynamic | area.Random):
    self.ToggleIsTour(event, 1)
elif ch == "V" and OnAnImage:
    self.WindowsPhotoViewer(event)
    return
elif ch == "W":
    self.ToggleWrap(event, 1)
elif ch == "Y" and not (area.Random | area.IsTour):
    self.ToggleDynamic(event, 1)
elif ch == "Z" and CanZapImage:
    self.Zap(event)
elif ch == "A" and not (area.Dynamic | area.IsTour):
    self.ToggleRandom(event, 1)
# Alt-R doesn't always work for some reason, so we give Alt-A as an 
alternative

else:
    event.Skip()
I'm well aware that if you apply PEP 8 guidelines strictly it would look 
like the above.  But is this supposed to be an improvement?  My original 
was a clear, tabular layout making the code structure completely clear, 
the vertical alignment *highlighting where different cases are treated 
differently and where they are treated similarly*.  This is just an 
amorphous mass of code that I find much harder to grok. (YMMV but I find 
it hard to imagine.)
Rules are all very well, but "A Foolish Consistency is the Hobgoblin of 
Little Minds" [PEP 8]

Best wishes
Rob
PS Can anyone shed any light on why Alt-R doesn't always "work" on 
Windows 10?  I believe there's some bit of installed software that has 
hijacked it, but I'm not sure what.


On Fri, Feb 12, 2021 at 1:46 AM Rob Cliffe via Python-ideas 
mailto:python-ideas@python.org>> wrote:




On 08/02/2021 00:39, Brendan Barnwell wrote:
> On 2021-02-07 09:59, Christopher Barker wrote:
>> All that being said, it's not that big a deal, and I personally
don't
>> try to limit to 80 chars per line anyway -- preferring 90 or 95
-- I
>> haven't used a VT100 in decades 
>
> To be honest I find it kind of ridiculous that people are still
> worrying about line lengths in this day and age.  It's especially
> strange that people will talk about how a proposed feature
interacts
> with relatively sophisticated editor/IDE features like syntax
> highlighting and autocompletion, yet still have no problem working
> with editors that are woefully limited on a much more basic
feature.
> It's called line wrapping.
>
> We as humans should not be concerned with how long LOGICAL
lines
> are until and unless it actually impinges on our ability to
comprehend
> them.  The appearance of the VISUAL line should not enter into our
> decision-making because that's a matter for the editor
displaying the
> code.  There's no reason not have lines that are 200 or 300 or even
> 1000 characters long if you want to (for instance for a long string
> literal); it's the editor's job to take a semantically-motivated
set
> of lines and indentations and display them attractively. Then if
 

[Python-ideas] Re: Alternate lambda syntax

2021-02-14 Thread Paul Sokolovsky
Hello,

On Sat, 13 Feb 2021 14:33:43 -0800
Christopher Barker  wrote:

> There seems to be a frequent objection to the word "lambda" --
> personally, I found it cryptic, but it's not hard to remember, and it
> IS easy to look up.

There seems to be a bit too many posts downputting the "lambda"
keyword, and nobody went for its defense, so let me do that. The
"lambda" is perhaps the greatest thing in Python after... after...
well, maybe it's the single greatest thing in Python.

As someone coming to Python from LISP (many years ago), I really
appreciate it, and always considered Python to be "a LISP for real
world".

So, it's of great utility to people familiar with functional
programming, but even of more utility to novices who are not yet -
thanks to it, by looking it up, they can get acquainted with the
wonderful world of functional programming and history of programming
languages.

Lambda is a sacred keyword, please don't touch! 

-- 
Best regards,
 Paul  mailto:pmis...@gmail.com
___
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@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/OQ77ILWZERPL27U5A5BDH3YOYFW3DIRM/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: Alternate lambda syntax

2021-02-14 Thread Steven D'Aprano
Be bold, they say...


On Mon, Feb 15, 2021 at 02:13:38AM +1100, Steven D'Aprano wrote:

> If I'm wrong, I'm sure somebody will point that out. I'm not frightened 
> of making bold claims that turn out to be wrong: that just means I have 
> learned something new. (Or something old that I forgot.)

Okay, there is an ambiguity, if arrow function syntax includes 
annotations with the syntax I suggested. I had:

(values:List[float], arg:int=0 -> Type) -> expression

Using that syntax, there is an ambiguous case:

(arg=(a, b) -> T) -> expression

That could mean:

* Default value of arg is the arrow function `(a, b) -> T`;

* Or the default value of arg is the tuple `(a, b)`, and the arrow 
  function has the return type T.

This may suggest that, like lambda, we should just not allow annotations 
in arrow functions; or that we need a better way to include the return 
annotation.

The third fix is to use `=>` for the arrow functions, but this has many 
down-sides, as previously discussed.

Anyway, the rest of my claim still stands (I think): if arrow functions 
don't include annotations there is no ambiguity between function 
annotations and arrow functions.


-- 
Steve
___
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@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/FFXEX54RWDCWEZ2D2DENQEZCZ2WYVGWJ/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: Pattern Matching -- Removing Name Binding from Partial Matching

2021-02-14 Thread Chris Angelico
On Sun, Feb 14, 2021 at 11:26 PM Abdulla Al Kathiri
 wrote:
>
> My idea was that in the case of partial matching or full matching without 
> passing the guard, the binding names has some sort of self destruction and 
> return to the previous state. Using different variable names would resolve 
> the issue and if I want to modify the global variables, I could choose to do 
> so in the case block after the case succeeded. At least, this way, it would 
> be more explicit, conveying the person intention (or forgetting if the 
> original global value was later needed). I saw many people online talking 
> about this the last couple of days so I thought I would bring it up here.  
> Any other syntax variant could be used to achieve the same thing.
>

It's not about syntax. Python doesn't have an idea of "self
destruction and return to the previous state". The nearest equivalent
is a very special case at the end of an exception handler, where after
"except Exception as e:" you'll get an implicit "e = None; del e" to
prevent a refloop. That's not a return to the previous state, that's a
conscious clearing of one reference.

If this "unwinding" were desired, the best way would be to simply make
it a permanent part of the match semantics - no syntax for selecting
which behaviour you want. There's no backward compatibility to be
maintained (yet). But that would be inconsistent with the rest of
Python, where things happen step by step, and if something breaks,
everything prior to it has happened.

ChrisA
___
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@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/5K65WY7B6O7EO5ZKWZZCS3OYV2HCIBQJ/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: Alternate lambda syntax

2021-02-14 Thread Steven D'Aprano
On Sun, Feb 14, 2021 at 11:23:59AM +0300, Paul Sokolovsky wrote:

> > We've seen Paul mistake => for >= and he's not the only one.
> 
> Well, my mistake is based on the fact that I don't spend high-level
> neurons on remembering mundane low-level things, like order of
> characters if the "greater or equals" operator. Instead, low-level
> hands motor function neurons get it right when I type (most of the time
> ;-)).

That would be just great if code was written more than it is read.

("Doesn't matter that people reading the code confusion the symbols, 
nobody reads it; what matters is that my hands know what to type.")

Or if we had a rule that only Python developers with a minimum of 10 
years experience are allowed to use it.


[...]
> > We already have chosen -> as the return type symbol in annotations, 
> > there is no ambiguity with also using it as the return value symbol.
> 
> You're mastermind to claim it like that. I for one wasn't sure there's
> no grammar-level ambiguity.

If I'm wrong, I'm sure somebody will point that out. I'm not frightened 
of making bold claims that turn out to be wrong: that just means I have 
learned something new. (Or something old that I forgot.)

My reasoning is this:

The arrow return annotation in def functions is only legal outside of 
the parameter list, and if it is there at all, it must immediately 
follow the parameter list.

def func(params) -> ret_expression:

So any time you see a def with a parameter list, inside the parameter 
list any arrows have to be the arrow function syntax. The first arrow 
immediately following the parameter list must be the return annotation, 
and any arrows following that must be part of ret_expression which could 
of course include more arrow functions.

No matter how complicated the parameter list gets, the parser will never 
expect that return annotation arrow until the parameter list has 
completed and the closing parenthesis has been seen. Even if it is an 
unreadable mess to the human reader, to the interpreter it ought to be 
completely unambiguous: until you hit that closing parenthesis, you're 
still in the parameter list and so no arrow can be the function 
annotation arrow.

Am I right so far?

Things get a bit more complex if the arrow functions themselves can 
include annotations. Lambdas don't, so perhaps these won't either.

But if they do, I have assumed a syntax like this:

(a:T, b:T, c:T -> T) -> body

where the return type annotation is inside the bracketed argument list. 
Each of those "T"s are, naturally, arbitrary expressions, so they could 
also include arrow functions. But the parser can always tell if it is 
looking inside the parameter list, and if so, if it is a default value, 
an annotation, the return annotation, or if it has reached the end of 
the parameter list and is now in the body.

And of course, nothing in the arrow function (not the parameter 
annotations, default values, the return annotation, or the body) can 
contain a def with its `->` arrow.

So I am:

- very confident that there is no ambiguity between def function return 
  annotations and arrow functions if they don't include annotations (as
  lambdas do not);

- not so confident if they do support annotations;

- but in that case, it ought to be resolvable.

There you go: I have boldly laid my neck out on the chopping block. If I 
am wrong, I will be happy to be corrected.


> But there another problem, on humans' side. For humans, it's very
> helpful when different concept look somewhat different. 

And it is also very helpful to have similar concepts look similar.

Return a value? The critical term here is **return**.

Return type? The critical term here is also **return**.


> And it's very
> helpful to use different arrows for values vs types.

Why is it helpful? Helpful to whom?

I can see that it would be helpful to have different arrows if there 
were cases where the reader wasn't sure whether they were looking at an 
annotation or an arrow function, but I don't think that will ever be the 
case.


> > We could even allow both:
> > 
> > (values:List[float], arg=0:int -> Type) -> expression
> 
> I for one can't parse that (didn't have a morning coffee, but suspect
> there's a typo/thinko).

Yes, I swapped the order of the default value and the type annotation, 
it should read:

(values:List[float], arg:int=0 -> Type) -> expression

Sorry for the confusion.

In case anyone is still having trouble parsing that:

# lambda version
lambda values, arg=0: expression

# becomes arrow function
(values, arg=0) -> expression

# add parameter annotations
(values:List[float], arg:int=0) -> expression

# and the return type of the function body (expression)
(values:List[float], arg:int=0 -> T) -> expression


> Btw, I'm not sure about function values, but
> IMHO, type notation should always use parens for arguments, e.g. "(int)
> -> int".

What is this type notation you are talking about, and 

[Python-ideas] Re: Arrow functions polyfill

2021-02-14 Thread Chris Angelico
On Sun, Feb 14, 2021 at 8:42 PM Steven D'Aprano  wrote:
> We should not choose the more confusing, error-prone solution out of
> fear of being different. Python is already different from Javascript in
> every regard:
>

Is it really?

> - the basic execution model is different;
Don't know what you mean here, but I thought they were the same.

> - the object model is different;
Same object model.

> - the numeric model is different;
Python has more data types, but that's not as fundamental a difference
as you might think

>  -the truthy/falsey model is different;
There are different rules about WHAT is truthy/falsy, but, again, the
differences aren't fundamental

> - the syntax is different;
> - the list of keywords is different;
> - the standard library is different;
> - the list of operators is different;
Well, of course. If these four were the same, they'd be the same
language. These four differ between Py2 and Py3 too.

> - even basic equality is different;
Yes, although that's more historic than anything else - most people
use "===" which has mostly the same semantics as Python's equality

> - the culture of the community is different.
TBH neither community has a single culture.


https://tvtropes.org/pmwiki/pmwiki.php/Main/NotSoDifferent

Python and JavaScript can learn a LOT from each other, because the
languages are actually pretty similar. Yes, of course there are
differences, but there are similarities too. Python has fewer
similarities with C than with JS, but still enough to learn from.

> "Javascript spells it this way" might be a compelling argument if the
> choice between the two symbols was neutral, but it isn't:
>
> * the double line arrow => is confusable with greater-than-or-equal;
>
> * the single line arrow -> is already used in Python for a related,
>   but unambiguously distinct, meaning.
>

I think this is the key to the whole argument. *IS it* unambiguously distinct?

There are enough other languages using "=>" AND enough other languages
using "->" that using either in Python will be following prior art.
The only real difference is that Python has one of them in use, and
the other not in use.

I personally don't much care whether it's spelled "=>" or "->", but
I'd say the best way to judge the potential ambiguity is to try it
with "->" and see how it looks.

ChrisA
___
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@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/YJH4QMVDCHCIKRXYVICWV4I3Q6E62VZO/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: Alternate lambda syntax

2021-02-14 Thread Abdulla Al Kathiri

def func(x: int, y: int, f: (int, int) -> int) -> int:
return f(x, y)

print(func(1, 4, (x, y) -> x + y)) #Output: 5
 
I think we can still use the same syntax for both typing.Callable and lambda. 
It would act like Callable if it comes after the “:” in annotations or after 
the “->” in function return annotation. After assignment or using it directly 
as an argument, then it acts like lambda. 

func: (str, str) -> None = (text1, text2) -> print(text1 + text2)
Same syntax, but communicates two different things. I don’t see any problem 
with this.
func: (str, str) -> None = (text1, text2) => print(text1 + text2) is not bad 
either to be honest. 

> On 14 Feb 2021, at 12:23 PM, Paul Sokolovsky  wrote:
> 
> I for one can't parse that (didn't have a morning coffee, but suspect
> there's a typo/thinko). Btw, I'm not sure about function values, but
> IMHO, type notation should always use parens for arguments, e.g. "(int)
> -> int".

___
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@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/FT6E4E2B7QBGAM5PVA3D4JPFVHEP5XRJ/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: Alternate lambda syntax

2021-02-14 Thread Serhiy Storchaka
11.02.21 13:24, J. Pic пише:
> Lambdas can be defined as such:
> 
> w = lambda: [12]
> x = lambda y: len(y)
> 
> I'd like to propose the following:
> 
> w = (): [12]
> x = (y): len(y)

This syntax is ambiguous.

if (y): len(y):

What does the first colon mean? You cannot say until you read the second
colon. It is difficult to parse for human and computer. While the
current PEG parser perhaps can handle this, it still makes parsing
slower and the code more errorprone.

Lambda is a questionable feature at all. With support of comprehensions,
local functions, the operator and functools modules there are not many
use cases for lambda expression. They are supported, well, but it is not
significant part of the language.
___
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@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/HX4LSMUPUGA65GQNNITM6RBPDRI34YFA/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: Pattern Matching -- Removing Name Binding from Partial Matching

2021-02-14 Thread Abdulla Al Kathiri
My idea was that in the case of partial matching or full matching without 
passing the guard, the binding names has some sort of self destruction and 
return to the previous state. Using different variable names would resolve the 
issue and if I want to modify the global variables, I could choose to do so in 
the case block after the case succeeded. At least, this way, it would be more 
explicit, conveying the person intention (or forgetting if the original global 
value was later needed). I saw many people online talking about this the last 
couple of days so I thought I would bring it up here.  Any other syntax variant 
could be used to achieve the same thing. 
> On 13 Feb 2021, at 9:51 PM, Guido van Rossum  wrote:
> 
> The solution here is not to use the same name for two different concepts in 
> the first place. Python doesn't have scopes associated with blocks, only with 
> functions, and occasionally this means you have to pick your names carefully 
> -- the same happens e.g. if you reuse a variable as a for-loop control 
> variable.
> 
> You can say that you don't want failed cases to bind any variables -- but 
> what if the pattern succeeds and now a guard (the 'if' clause) needs to check 
> the variable? We went down the route of how to make this work and in the end 
> decided it would be too complicated.
> 
> Or what if a case succeeds, and then after the match statement is over and 
> done with (not in `case _:`) you still wanted access to the global 'name'? 
> The long and short of it is that match statements are liable to any or all 
> names bound in any of the patterns used, and your code is incorrect if you 
> aren't prepared for that.
> 
> A variant of the syntax to allow alternate semantics sounds worse.
> 
> On Fri, Feb 12, 2021 at 10:30 PM Abdulla Al Kathiri 
> mailto:alkathiri.abdu...@gmail.com>> wrote:
> I will explain it in the following few lines of code..
> 
> name = "George"
> year = 2021
> 
> d = {"name": "Mike", "year": 1919}
> 
> match d:
> 
> case {"name": name, "year": 1917}:
> print("match 1 found”)
> # I want to remove binding "name" here from partial matching
> 
> case {"year": year, "name": "Michael”}:
> print("match 2 found”)
> # I want to remove binding "year" here from partial matching. 
> # Basically removing all name bindings after every 
> partial/failed matching 
> 
> case _:
> print("match not found!”)
> print(f"{name = }, {year = }”)
> 
> ### Output ###: 
> match not found!
> name = 'Mike', year = 1919
> 
> But I want :var: 'name' to stay being the global name “George" and :var: 
> 'year' being the global year 2021 if an exact matching is not found.
> 
> Maybe it is done the way it is for speed optimization (overhead reduction or 
> something), but what if I don't care about speed and I care about having no 
> un-intentional side-effects? 
> 
> Can we do something like the following to solve this issue?
> match d, partial_binding=False:
> case … : ...
> case … : ...
> with partial_binding=True by default.
> 
> Any other idea in how to prevent name binding due to partial matching from 
> happening? Any previous discussions on this? 
> 
> Thanks, 
> 
> Abdulla
> ___
> Python-ideas mailing list -- python-ideas@python.org 
> 
> To unsubscribe send an email to python-ideas-le...@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/HOFNVZ6KJA6SHCE4NCLPSK27XLDMK7VR/
>  
> 
> Code of Conduct: http://python.org/psf/codeofconduct/ 
> 
> 
> 
> -- 
> --Guido van Rossum (python.org/~guido )
> Pronouns: he/him (why is my pronoun here?) 
> 
___
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@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/7L5KOHIIVN5K2LJLWFOUBYB4OXHXQ4AJ/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: Alternate lambda syntax

2021-02-14 Thread anthony.flury via Python-ideas



On 12/02/2021 07:32, Paul Sokolovsky wrote:

Hello,

On Fri, 12 Feb 2021 18:26:53 +1100
Chris Angelico  wrote:


On Fri, Feb 12, 2021 at 6:24 PM Paul Sokolovsky 
wrote:

... And on the 2nd thought, that won't work. The reason it works in
JS is that it doesn't have tuples. In Python, "(a, b) => (1, 2)"
means "compare a tuple for greater-or-equal".

Should be safe actually - "=>" is not a valid comparison operator.
It may not be a valid operator - but it reads as if it could be. using 
'=>' for this will decrease the readability as far as I can see.


It takes a bit of mental processing to realise this isn't a valid 
comparison, and then more processing to understand what it does mean; it 
will definitely be a source of confusion for beginners. The fact that a 
very respected member of the community got it wrong at first sight 
suggests that many will do so.


If we were going to do this - and I am still on the fence - I think we 
should avoid anything that reads like it could be confused as an operator.

___
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@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/3SAONT64IU4LP4ML3XARVPESJKG25CY2/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: Arrow functions polyfill

2021-02-14 Thread Steven D'Aprano
On Sun, Feb 14, 2021 at 11:54:21AM +0300, Paul Sokolovsky wrote:

> > > b) Python already uses "->" for function return *type*. And there's
> > > idea to generalize it to *function type* in general. E.g. a function
> > > "(a, b) => a + b" can have type "(int, int) -> int".  
> > 
> > This supports the idea of using "->" as the "return operator". In 
> > annotations, it annotates the return *type* and in function bodies it 
> > marks the return *value*.
> > 
> > (a:int, b:int -> int) -> a*b
> > 
> > Why have two different "return operators"? That can only lead to 
> > confusion:
> 
> Because even calling them "return operators" is "abuse of notation".

You're right, thank you for the correction.

They aren't operators, although people will call them that, just as the 
speak of name.attr as "the dot operator".

Let me rephrase it: Why have two different return **symbols** when they 
are so closely related?


> And because things "returned" are wildly different. If first case, it's
> *value*, in second - it's *type*.

This is a small and unimportant difference, and with good type inference 
the second is redundant. The critical feature here is not what is 
returned, but the fact that it marks a return.

The first is a symbol that marks the value returned. The second is an 
annotation symbol that marks the type of the value returned.

There is no syntactic or semantic confusion between the two, the 
difference is obvious from context to both the human reader and the 
interpreter.

Having two different symbols for this would be like having two ever so 
slightly different keywords for for loops and comprehensions:

for x in sequence: block

[expression por x in sequence]

For loops are widely different from comprehensions! The first is a block 
statement, the second is an expression, these are completely different 
things and should have completely different keywords to avoid confusion!

No. This would *cause* confusion when people fail to remember the 
difference between for and por (Spanish, for those who wonder), and 
there would be a continual stream of people asking "what's the 
difference between for and por?"

And so there will be confusion when people fail to remember the 
difference between -> and => and have to ask what the difference is. And 
people will confuse => with >= as you already did.

Being different just for the sake of being different is a bad idea, but 
being different because -> is a better fit to the existing language is 
an excellent idea.

We should not choose the more confusing, error-prone solution out of 
fear of being different. Python is already different from Javascript in 
every regard:

- the basic execution model is different;
- the object model is different;
- the numeric model is different;
 -the truthy/falsey model is different;
- the syntax is different;
- the list of keywords is different;
- the standard library is different;
- the list of operators is different;
- even basic equality is different;
- the culture of the community is different.

"Javascript spells it this way" might be a compelling argument if the 
choice between the two symbols was neutral, but it isn't:

* the double line arrow => is confusable with greater-than-or-equal;

* the single line arrow -> is already used in Python for a related,
  but unambiguously distinct, meaning.



-- 
Steve
___
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@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/BB6USWWZABHIXNKVMVUO4N3SDQ4PUYSP/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: Arrow functions polyfill

2021-02-14 Thread Paul Sokolovsky
Hello,

On Sun, 14 Feb 2021 13:57:14 +1100
Steven D'Aprano  wrote:

> On Sun, Feb 14, 2021 at 12:47:30AM +0300, Paul Sokolovsky wrote:
> > Hello,
> > 
> > On Sat, 13 Feb 2021 16:25:24 -0500
> > Cade Brown  wrote:
> >   
> > > In my humble opinion, arrows should be '->' instead of '=>'. It
> > > always annoys me when languages use that symbol  
> > 
> > That's unlikely, as was discussed in this thread previously:
> > 
> > a) JavaScript already uses "=>", and it doesn't make sense to be
> > different just for the purpose of being different. That will only
> > confuse people.  
> 
> It's not being different for the sake of being different. It's being 
> different because Javascript gets it wrong, and we should get it
> right.
> 
> *semi-wink*
> 
> I wouldn't worry about being inconsistent with Javascript. We are 
> already inconsistent with Javascript in many, many, many ways. One
> more is no big deal.

There're 2 things about that from an experienced JavaScript-hater (but
a pragmatic guy otherwise):

1. We aren't talking about all of JavaScript, but a recent features
added to JS.
2. JS has real money being poured into it, and no longer designed on
two-week vacations, when nobody looks. On the JS committees/proposal
author lists are guys who have publications in serious programming
language design matters and "grown up" languages, like proverbial
Haskell. And they peer-review each other. So, with due understanding of
the baseline https://en.wikipedia.org/wiki/Design_by_committee process,
some recent features in JS are well-designed.

> 
> Other popular and influential languages include:

Please make sure this list ends up in the PEP, because we really, really
should explicitly learn/compare Python with other languages (that's
what actual users (or leavers) of the language do). 

[]

> The question we should be asking is not so much how popular
> Javascript is in absolute terms, but:
> 
> - how many people coming to Python will be familiar with Javascript
> as opposed to R, Julia, Maple, etc, or no language at all?

I think that the answer is "very many". JS is both companion and
competitor of Python. Companion, as very many people work on webapps
(best practice in application-level (not sytem-level) development
nowadays), and constantly switch between backend code in Python and
frontend (in-browser) code in JS. Competitor in everything else (and
making Python purposely different, which oftentimes translates to
"worse" doesn't help here).

> - given how many other things they will have to learn that is
> different, is one comparatively rarely used feature more that much of
> a burden?

Again, we're talking about specific recent things (one now, but we'll
be returning to that). And arrow functions are now very popular in JS,
so someone hearing that Python added will immediately proceed to check,
and on discovery that they look different, they'd conclude it was done
on purpose, to confuse people. 

> > b) Python already uses "->" for function return *type*. And there's
> > idea to generalize it to *function type* in general. E.g. a function
> > "(a, b) => a + b" can have type "(int, int) -> int".  
> 
> This supports the idea of using "->" as the "return operator". In 
> annotations, it annotates the return *type* and in function bodies it 
> marks the return *value*.
> 
> (a:int, b:int -> int) -> a*b
> 
> Why have two different "return operators"? That can only lead to 
> confusion:

Because even calling them "return operators" is "abuse of notation".
And because things "returned" are wildly different. If first case, it's
*value*, in second - it's *type*. These concepts are from different
levels (types are at meta-level of values), and mean very different
things.

> 
> # Which of these are correct?
> 
> (a, b) -> a*b

This is a function type, where arbitrary types are accepted, and
the function returns product type of them, i.e. a tuple. We unlikely
would use that notation, rather literal tuple notation, so it would be:

(a, b) -> (a, b) 

(But that's an idea how to "free up" tuple syntax in
new-style annotations for something else. But I don't think it would
fly).

> (a, b) => a*b

This is a function which returns things multiplied.

> 
> def func(a, b) -> Spam: pass

Normal familiar by now function annotation.

> def func(a, b) => Spam: pass

This is syntax error.

> # and if arrow functions allow annotations, it's even worse!

It's better, because it allows to distinguish value-level from type
meta-level.

> (a, b -> Type) -> a*b
> (a, b => Type) -> a*b
> (a, b -> Type) => a*b
> (a, b => Type) => a*b

In first approximation, these all are syntax errors. Practically, I
guess for arrow functions, we'll need to allow single args without
parens, e.g. "a => a + 1", then some of the above will make sense. (But
as I mentioned, IMHO exception shouldn't apply for types, or we go to
the land of functional-egghead confusion).

> Let's keep it nice and simple. We already 

[Python-ideas] Re: Alternate lambda syntax

2021-02-14 Thread Paul Sokolovsky
Hello,

On Sun, 14 Feb 2021 18:36:14 +1100
Steven D'Aprano  wrote:

> On Thu, Feb 11, 2021 at 09:36:25PM -0800, Guido van Rossum wrote:
> 
> > Agreed. I'd prefer the JavaScript solution, since -> already has a
> > different meaning in Python return *type*. We could use -> to
> > simplify typing.Callable, and => to simplify lambda.  
> 
> Please no! That will lead to constant confusion for people who can't 
> remember which arrow operator to use. Is -> the return type symbol or 
> the return value symbol? I forsee many Stackoverflow questions
> "What's the difference between -> and => ?"
> 
> We've seen Paul mistake => for >= and he's not the only one.

Well, my mistake is based on the fact that I don't spend high-level
neurons on remembering mundane low-level things, like order of
characters if the "greater or equals" operator. Instead, low-level
hands motor function neurons get it right when I type (most of the time
;-)). It's the same as I (and many other people I'm sure) don't
remember phone numbers nowadays - why, if modern phones well remember
them themselves, transfer from one instance to another, etc.

Bottom line: after not too long practice, nobody would confuse ">=" and
"=>", as they're different on their usage context (picked up
subconsciously).

> We already have chosen -> as the return type symbol in annotations, 
> there is no ambiguity with also using it as the return value symbol.

You're mastermind to claim it like that. I for one wasn't sure there's
no grammar-level ambiguity. Perhaps now I can say: if an arrow function
appears in the type annotation position, then well, it's a type. That
should work for the parser algorithm.

But there another problem, on humans' side. For humans, it's very
helpful when different concept look somewhat different. And it's very
helpful to use different arrows for values vs types.

> We could even allow both:
> 
> (values:List[float], arg=0:int -> Type) -> expression

I for one can't parse that (didn't have a morning coffee, but suspect
there's a typo/thinko). Btw, I'm not sure about function values, but
IMHO, type notation should always use parens for arguments, e.g. "(int)
-> int".

> There are plenty of popular and influential languages that use the 
> single line arrow -> such as Maple, Haskell, Julia, CoffeeScript,
> Erlang and Groovy, to say nothing of numerous lesser known and
> obscure languages.

The question is how many of those language have first-class type
literals, and how many use the same notation for function literals and
type literals. 

[]

-- 
Best regards,
 Paul  mailto:pmis...@gmail.com
___
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@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/VN6KKLPVOEQ63S6FGJV2J6YOBDAM6ZIO/
Code of Conduct: http://python.org/psf/codeofconduct/