Re: [Python-ideas] Does jargon make learning more difficult?

2018-08-21 Thread Stephen J. Turnbull
Chris Angelico writes:

 > I have to defer to someone who knows in more detail here, but the
 > parser will look ahead one "token", whatever a token is. (Technically
 > it doesn't backtrack, it looks ahead - same difference.)

Tokens are basically keywords, identifiers, most single punctuation
characters, and indentation.  Some strings of punctuation are tokens
by special dispensation.

 > In order for the ternary-if to work, the expression before the if
 > has to be of a more restricted type than just "any expression" (for
 > instance, you can't put a lambda function there, unless you
 > parenthesize it).

It's not that it's a restricted expression, it's that a valid lambda
will consist of a syntactically complete expression.  If you then
place "if" after that lambda without parenthesizing, the parser will
think that the lambda contains the whole ternary expression because
pretty much any Python expression has a value that can be implicitly
cast to bool.

Steve

___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] A simple proposal concerning lambda

2018-08-21 Thread Abe Dillon
[Chris Angelico]

> Though... it's insignificant when the function header precedes the
> expression/body. With the proposal to move the header to the end, that
> might become problematic, which makes it yet another cost to the
> proposal.


I don't think it would be a problem because, like ternary and other
circuiting operations, the expression isn't evaluated until certain
criteria are met.
The arrangement shouldn't matter.

...I think.

On Tue, Aug 21, 2018 at 10:10 PM Chris Angelico  wrote:

> On Wed, Aug 22, 2018 at 12:57 PM, Abe Dillon  wrote:
> > [Chris Angelico]
> >>
> >> If you have a use-case for a lambda function that takes a callback and
> >> has a default value for that callback, please submit it to The Daily
> >> WTF. In Steve's example, the main function was created with a
> >> statement.
> >
> >
> > Fair enough, but I still think D'Aprano may have engineered his example
> to
> > be particularly unreadable.
> > Why would you use 'arg' for both the argument to the method and the
> > callback! That's at least a little WTF.
>
> True, but hardly significant. The one inside lambda is local to it.
>
> Though... it's insignificant when the function header precedes the
> expression/body. With the proposal to move the header to the end, that
> might become problematic, which makes it yet another cost to the
> proposal.
>
> ChrisA
> ___
> Python-ideas mailing list
> Python-ideas@python.org
> https://mail.python.org/mailman/listinfo/python-ideas
> Code of Conduct: http://python.org/psf/codeofconduct/
>
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] A simple proposal concerning lambda

2018-08-21 Thread Chris Angelico
On Wed, Aug 22, 2018 at 12:57 PM, Abe Dillon  wrote:
> [Chris Angelico]
>>
>> If you have a use-case for a lambda function that takes a callback and
>> has a default value for that callback, please submit it to The Daily
>> WTF. In Steve's example, the main function was created with a
>> statement.
>
>
> Fair enough, but I still think D'Aprano may have engineered his example to
> be particularly unreadable.
> Why would you use 'arg' for both the argument to the method and the
> callback! That's at least a little WTF.

True, but hardly significant. The one inside lambda is local to it.

Though... it's insignificant when the function header precedes the
expression/body. With the proposal to move the header to the end, that
might become problematic, which makes it yet another cost to the
proposal.

ChrisA
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] A simple proposal concerning lambda

2018-08-21 Thread Abe Dillon
[Chris Angelico]

> If you have a use-case for a lambda function that takes a callback and
> has a default value for that callback, please submit it to The Daily
> WTF. In Steve's example, the main function was created with a
> statement.


Fair enough, but I still think D'Aprano may have engineered his example to
be particularly unreadable.
Why would you use 'arg' for both the argument to the method and the
callback! That's at least a little WTF.
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] A simple proposal concerning lambda

2018-08-21 Thread Chris Angelico
On Wed, Aug 22, 2018 at 12:48 PM, Abe Dillon  wrote:
> [Steven D'Aprano]
>>
>> Replacing the keyword:
>> results = map(def a, b=2, c=3: a ** b / c, sequence)
>> widget.register(callback=def: spam.eggs())
>> Doesn't look so attractive now, I wager. Using "def" inside an
>> expression looks strange. And this looks outright disturbing:
>> def method(self, arg, callback=def arg: arg+1):
>> pass
>
>
> Eh... I think they look fine. Which is worse:
>
> def method(self, arg, callback=def arg: arg+1):
> pass
>
> or
>
> lambda arg, callback=lambda arg: arg+1: None
>
> because the second one makes me go cross-eyed...

If you have a use-case for a lambda function that takes a callback and
has a default value for that callback, please submit it to The Daily
WTF. In Steve's example, the main function was created with a
statement.

ChrisA
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] A simple proposal concerning lambda

2018-08-21 Thread Abe Dillon
[Steven D'Aprano]

> most importantly, "def" with "fun", which will have the
> advantage of making Python programming more fun!


I'm sold. Make the change and SHIP IT!
No need for committee approval.

[Steven D'Aprano]

> If we're going to break people's code by
> changing keywords, let's do it properly! *wink*


I'm not backing this proposal, but I am curious what the proposal could
break.

[Steven D'Aprano]

> - Two fewer keystrokes.


THREE!!!

[Steven D'Aprano]

> - but "def" is still jargon that needs to be learned.


It already has to be learned and it's already associated with function
declaration.

[Steven D'Aprano]

> I don't think this cosmetic change comes even close to the break-even
> point of costs versus benefits. Maybe if we were designing Python from
> scratch today, there would be a good argument to be made for using def
> in both the statement and expression form, but even that's not a sure
> thing. Changing it *now* is more costly with less benefit.


Yeah, that's pretty much my take on the matter.
That ship sailed way back when Py3k was finalized.

[Steven D'Aprano]

> To give an example of a problematic keyword where changing it is not
> just cosmetic, for many years, consider the "for...else" statement. It
> seems to be saying:
> run the for loop
> *or else* run this block
> but that's not what it actually means. But even if we had consensus that
> the "else" keyword should be changed (to what? "then" is my suggestion),
> the benefit is probably too small to disrupt the Python ecosystem by
> actually making that change.


for-finished?
for-done?
for-stopped?  # referencing StopIteration
for-anything_but_else?

[Steven D'Aprano]
>
> By the way, I'll also point out that the way you have demonstrated the
> use of anonymous functions is considered a (mild) abuse of syntax. Your
> example:
> # reverting back to lambda for the moment
> hn = lambda a, b=2, c=3: a ** b / c
> ought to be written as:
>def hn(a, b=2, c=3): return a ** b / c


Oh, come-on; D'Aprano! That was just to demonstrate properties of the
resulting object.
It's not meant to be production code.

[Steven D'Aprano]

> Replacing the keyword:
> results = map(def a, b=2, c=3: a ** b / c, sequence)
> widget.register(callback=def: spam.eggs())
> Doesn't look so attractive now, I wager. Using "def" inside an
> expression looks strange. And this looks outright disturbing:
> def method(self, arg, callback=def arg: arg+1):
> pass


Eh... I think they look fine. Which is worse:

def method(self, arg, callback=def arg: arg+1):
pass

or

lambda arg, callback=lambda arg: arg+1: None

because the second one makes me go cross-eyed...

On Tue, Aug 21, 2018 at 8:55 PM, Steven D'Aprano 
wrote:

> On Tue, Aug 21, 2018 at 10:27:20PM +0100, Jonathan Fine wrote:
>
> > Here is my simple proposal. Enhance Python to allow
> >
> > >>> hn = def a, b=2, c=3: a ** b / c
>
> Enhancements ought to allow us to write new code that we couldn't do
> before, or open up new kinds of algorithms that weren't easy or possible
> before.
>
> This is a mere cosmetic change, replacing a perfectly valid keyword with
> one which clashes with an existing keyword in what I consider to be an
> ugly way.
>
> While we're at it, perhaps we ought to replace:
>
> - "else" with "otherwise"
>   ("else" is a weird word, outside of programming we hardly ever use it
>   without a leading "or")
>
> - "import" with "load" (shorter)
>
> - "for" with "repeat with"
>   (I've always found it awkward that the word "for" sounds like an number)
>
> - "raise" with "throw"
>
> - and most importantly, "def" with "fun", which will have the
>   advantage of making Python programming more fun!
>
> Admittedly these run into backwards-compatibility issues, which your
> suggestion does not. But if we're going to break people's code by
> changing keywords, let's do it properly! *wink*
>
> Changing the public API of a language, its keywords, is not something to
> be done lightly. The consequences of such a change can include:
>
> - breaking backwards compatibility;
>
> - code churn (people have to "fix their code" even if it wasn't broken);
>
> - confusion ("what's the difference between def anonymous functions
>   and lambda anonymous functions?");
>
> - more to learn during the transition (sometimes code uses lambda,
>   sometimes def, so you need to know both)
>
> - more documentation explaining why the name is only sometimes needed;
>
> - more unit tests etc to ensure the feature works correctly, e.g. to
>   test for the syntax error when people use def unanonymously when
>   they should use it anonymously:
>
>   map(def func(a, b, c): a+b-c, zip(seq1, seq2, seq3))
>
>
> Those costs are real and should only be paid when the benefits outweigh
> the costs. In this specific case, there's also a very real cost:
>
> - you will *seriously annoy and frustrate* those of us who like lambda
>   and dislike the look of "def" inside expressions;
>
> - while only 

Re: [Python-ideas] A simple proposal concerning lambda

2018-08-21 Thread MRAB

On 2018-08-22 02:38, Elazar wrote:
I don't think this change makes sense, but if it's done, there should be 
another change, with actual implications:
There is no way to express the types of the parameters in a lambda - 
`lambda x: int : x` is obviously a syntax error. Replacing the colon 
with a different symbol, such as "=>" will make this possible:


     def x => x
     def x: int => x
     def x: int -> int => x

It will also give one less meaning to the colon.


The examples I showed had parens, so your examples could be:

def (x): x
def (x: int): x
def (x: int) -> int: x



On Tue, Aug 21, 2018 at 6:28 PM MRAB > wrote:


On 2018-08-22 01:25, Jonathan Fine wrote:
 > Hi Abe
 >
 > Summary: You've done good work here. I've skim read the 2006
 > discussion you found.
 >
 > You wrote:
 >
 >> I'm trying to dig up past threads about alternatives to lambda
because I
 >> would be astonished if "def" hadn't been considered and rejected
for some
 >> reason. What I've found so far is this unreassuring  post from
Guido back in
 >> 2006
 >
 >> [Python-Dev] Let's just *keep* lambda
 >>
https://mail.python.org/pipermail/python-dev/2006-February/060415.html
 >
 > This is an excellent piece of work. I'm most grateful. Here's
what Guido said:
 >
 >> After so many attempts to come up with an alternative for lambda,
 >> perhaps we should admit defeat. I've not had the time to follow the
 >> most recent rounds, but I propose that we keep lambda, so as to stop
 >> wasting everybody's talent and time on an impossible quest.
 >
 > I've quickly read through the posts that followed Guido's message,
 > picked out the ones that interest me. Here's a list.
 >
 >>
https://mail.python.org/pipermail/python-dev/2006-February/060487.html
 >>
https://mail.python.org/pipermail/python-dev/2006-February/060474.html
 >>
https://mail.python.org/pipermail/python-dev/2006-February/060471.html
 >>
https://mail.python.org/pipermail/python-dev/2006-February/060445.html
 >>
https://mail.python.org/pipermail/python-dev/2006-February/060435.html
 >>
https://mail.python.org/pipermail/python-dev/2006-February/060431.html
 >>
https://mail.python.org/pipermail/python-dev/2006-February/060470.html
 >
 > And one of the messages had a link to still live and excellent page
 >
 >> https://wiki.python.org/moin/AlternateLambdaSyntax
 >
 > This page lists over 100 suggestions, mostly variants. So far as
I can
 > see, my simple proposal isn't listed on that page. The page also says
 >
Hmm.

That lists:

      def (a, b, c): return f(a) + o(b) - o(c)

and:

      def (a, b, c) = f(a) + o(b) - o(c)

but not:

      def (a, b, c): f(a) + o(b) - o(c)

 >> **Definitely Desirable Features**
 > [snip]
 >> *More friendly to inexperienced users*
 > [snip]
 >> Compared to other Python keywords, 'lambda' is rather esoteric.
 >> In the challenge for "farthest outside day-to-day English usage",
 >> its closest competitor would probably be 'assert', as even 'def'
 >> and 'elif' are just abbreviations for 'define' and 'else if'. Use of
 >> simpler keywords may make deferred expressions appear less
 >> intimidating than they seem with the current unusual keyword.
 >
 > The word 'deferred' appears 7 times on the page. It also appears in
 > the python-dev messages.
 >
 > If someone with more time and less bias then myself were to summarise
 > this discussion from 2006, I'd be most grateful, and they'd have
 > material for a great blog post.
 >
 > Finally, many thanks to Abe for finding this gem, and countless
 > people's hard work in keeping it alive to be found. Backwards
 > compatibility is there for a reason.
 >

___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] A simple proposal concerning lambda

2018-08-21 Thread Abe Dillon
[Jonathan Fine]

> one of the messages had a link to still live and excellent page
> > https://wiki.python.org/moin/AlternateLambdaSyntax
> This page lists over 100 suggestions, mostly variants. So far as I can
> see, my simple proposal isn't listed on that page. The page also says


Awesome!

Unfortunately the links to conversations seem to all be broken!

Most of the links are from December 2004, so I pulled up the discussion for
that month

and searched "lambda"

I was able to find what I believe is reference [1]:
https://mail.python.org/pipermail/python-list/2004-December/264515.html

It looks like the post numbers got mangled...

Anyway, it looks like that page covers December 2004-June 2005, I found a
few nuggets of opposition:

https://mail.python.org/pipermail/python-list/2004-December/247348.html

https://mail.python.org/pipermail/python-list/2004-December/273038.html

I sort-of understand the opposition to multi-line anonymous functions, but
I think the Terry Reedy (in the second link)
is a bit too dismissive of the concept of anonymous functions.

I don't work with user-interfaces a lot, but when I do; I can see why UI
coders use anonymous functions so much.
Defining a function in a statement can be far less expressive and far more
noisy than in an expression.
It's like: I'll tell you my solution, but first let me shave this Yak here.

You're defining often one-off functions before describing what you're going
to use it for.
It's only after you actually pass them to an event-watcher that the context
of their logic is clear.
For instance:

>>> def handler(event):  # First, let me tell you about a function
...   # It's a 1-off with a throw-away name
... return result  # You'll see what I need it for later...
...
>>> ui_element.on_mouseover(handler)

vs.

>>> # lack of noisy preamble to your code
>>> ui_element.on_mouseover( with event)

The anonymous function is given meaning by virtue of the context in-which
it's defined.
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] A simple proposal concerning lambda

2018-08-21 Thread Stephen J. Turnbull
Abe Dillon writes:

 > What I've found so far is this unreassuring post from Guido back in
 > 2006
 > 

IIRC, early drafts of PEP 3000 (the PEP that was the planning document
for the Python 3 project) removed lambda altogether.  However there
was strong opposition, so we ended up keeping lambda.  Some of those
discussions morphed to ideas about "improving" lambda.  So you may find
discussions of lambda in threads titled "PEP 3000" or "Python 3000".


-- 
Associate Professor  Division of Policy and Planning Science
http://turnbull.sk.tsukuba.ac.jp/ Faculty of Systems and Information
Email: turnb...@sk.tsukuba.ac.jp   University of Tsukuba
Tel: 029-853-5175 Tennodai 1-1-1, Tsukuba 305-8573 JAPAN
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] A simple proposal concerning lambda

2018-08-21 Thread Steven D'Aprano
On Tue, Aug 21, 2018 at 10:27:20PM +0100, Jonathan Fine wrote:

> Here is my simple proposal. Enhance Python to allow
> 
> >>> hn = def a, b=2, c=3: a ** b / c

Enhancements ought to allow us to write new code that we couldn't do 
before, or open up new kinds of algorithms that weren't easy or possible 
before.

This is a mere cosmetic change, replacing a perfectly valid keyword with 
one which clashes with an existing keyword in what I consider to be an 
ugly way.

While we're at it, perhaps we ought to replace:

- "else" with "otherwise"
  ("else" is a weird word, outside of programming we hardly ever use it 
  without a leading "or")

- "import" with "load" (shorter)

- "for" with "repeat with" 
  (I've always found it awkward that the word "for" sounds like an number)

- "raise" with "throw"

- and most importantly, "def" with "fun", which will have the 
  advantage of making Python programming more fun!

Admittedly these run into backwards-compatibility issues, which your 
suggestion does not. But if we're going to break people's code by 
changing keywords, let's do it properly! *wink*

Changing the public API of a language, its keywords, is not something to 
be done lightly. The consequences of such a change can include:

- breaking backwards compatibility;

- code churn (people have to "fix their code" even if it wasn't broken);

- confusion ("what's the difference between def anonymous functions 
  and lambda anonymous functions?");

- more to learn during the transition (sometimes code uses lambda, 
  sometimes def, so you need to know both)

- more documentation explaining why the name is only sometimes needed;

- more unit tests etc to ensure the feature works correctly, e.g. to 
  test for the syntax error when people use def unanonymously when
  they should use it anonymously:

  map(def func(a, b, c): a+b-c, zip(seq1, seq2, seq3))


Those costs are real and should only be paid when the benefits outweigh 
the costs. In this specific case, there's also a very real cost:

- you will *seriously annoy and frustrate* those of us who like lambda 
  and dislike the look of "def" inside expressions;

- while only *slightly pleasing* those who have already learned lambda
  but don't like it. They've already learned the existing word, now they 
  have to unlearn it.

And the corresponding benefit is tiny:

- The conceptual difficulties with lambda is not the word but the
  concept of anonymous functions as first class values; that doesn't 
  change, so no benefit there.

- One less keyword in the language (after the transition period).

- Two fewer keystrokes.

- but "def" is still jargon that needs to be learned.

(Does it mean defeat, defame, defer, defend, or that thing bears do in 
the woods? To a non-English speaker, memorising "def" = "define" is no 
less obscure than memorising "lam" = "lambda" would be for English 
speakers.)

I don't think this cosmetic change comes even close to the break-even 
point of costs versus benefits. Maybe if we were designing Python from 
scratch today, there would be a good argument to be made for using def 
in both the statement and expression form, but even that's not a sure 
thing. Changing it *now* is more costly with less benefit.

To give an example of a problematic keyword where changing it is not 
just cosmetic, for many years, consider the "for...else" statement. It 
seems to be saying:

run the for loop

*or else* run this block

but that's not what it actually means. But even if we had consensus that 
the "else" keyword should be changed (to what? "then" is my suggestion), 
the benefit is probably too small to disrupt the Python ecosystem by 
actually making that change.

By the way, I'll also point out that the way you have demonstrated the 
use of anonymous functions is considered a (mild) abuse of syntax. Your 
example:

# reverting back to lambda for the moment
hn = lambda a, b=2, c=3: a ** b / c 

ought to be written as:

   def hn(a, b=2, c=3): return a ** b / c

which ensures that hn has a nice name for debugging. Lambdas ought to be 
limited to in-place uses, as part of a larger expression and not just an 
assignment, probably 99% of the time. Hence:

results = map(lambda a, b=2, c=3: a ** b / c, sequence)

widget.register(callback=lambda: spam.eggs())

are reasonable examples of how one might find lambdas in the wild. 
Replacing the keyword:

results = map(def a, b=2, c=3: a ** b / c, sequence)

widget.register(callback=def: spam.eggs())

Doesn't look so attractive now, I wager. Using "def" inside an 
expression looks strange. And this looks outright disturbing:

def method(self, arg, callback=def arg: arg+1):
pass



-- 
Steve
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] A simple proposal concerning lambda

2018-08-21 Thread Elazar
I don't think this change makes sense, but if it's done, there should be
another change, with actual implications:
There is no way to express the types of the parameters in a lambda -
`lambda x: int : x` is obviously a syntax error. Replacing the colon with a
different symbol, such as "=>" will make this possible:

def x => x
def x: int => x
def x: int -> int => x

It will also give one less meaning to the colon.

Elazar

On Tue, Aug 21, 2018 at 6:28 PM MRAB  wrote:

> On 2018-08-22 01:25, Jonathan Fine wrote:
> > Hi Abe
> >
> > Summary: You've done good work here. I've skim read the 2006
> > discussion you found.
> >
> > You wrote:
> >
> >> I'm trying to dig up past threads about alternatives to lambda because I
> >> would be astonished if "def" hadn't been considered and rejected for
> some
> >> reason. What I've found so far is this unreassuring  post from Guido
> back in
> >> 2006
> >
> >> [Python-Dev] Let's just *keep* lambda
> >> https://mail.python.org/pipermail/python-dev/2006-February/060415.html
> >
> > This is an excellent piece of work. I'm most grateful. Here's what Guido
> said:
> >
> >> After so many attempts to come up with an alternative for lambda,
> >> perhaps we should admit defeat. I've not had the time to follow the
> >> most recent rounds, but I propose that we keep lambda, so as to stop
> >> wasting everybody's talent and time on an impossible quest.
> >
> > I've quickly read through the posts that followed Guido's message,
> > picked out the ones that interest me. Here's a list.
> >
> >> https://mail.python.org/pipermail/python-dev/2006-February/060487.html
> >> https://mail.python.org/pipermail/python-dev/2006-February/060474.html
> >> https://mail.python.org/pipermail/python-dev/2006-February/060471.html
> >> https://mail.python.org/pipermail/python-dev/2006-February/060445.html
> >> https://mail.python.org/pipermail/python-dev/2006-February/060435.html
> >> https://mail.python.org/pipermail/python-dev/2006-February/060431.html
> >> https://mail.python.org/pipermail/python-dev/2006-February/060470.html
> >
> > And one of the messages had a link to still live and excellent page
> >
> >> https://wiki.python.org/moin/AlternateLambdaSyntax
> >
> > This page lists over 100 suggestions, mostly variants. So far as I can
> > see, my simple proposal isn't listed on that page. The page also says
> >
> Hmm.
>
> That lists:
>
>  def (a, b, c): return f(a) + o(b) - o(c)
>
> and:
>
>  def (a, b, c) = f(a) + o(b) - o(c)
>
> but not:
>
>  def (a, b, c): f(a) + o(b) - o(c)
>
> >> **Definitely Desirable Features**
> > [snip]
> >> *More friendly to inexperienced users*
> > [snip]
> >> Compared to other Python keywords, 'lambda' is rather esoteric.
> >> In the challenge for "farthest outside day-to-day English usage",
> >> its closest competitor would probably be 'assert', as even 'def'
> >> and 'elif' are just abbreviations for 'define' and 'else if'. Use of
> >> simpler keywords may make deferred expressions appear less
> >> intimidating than they seem with the current unusual keyword.
> >
> > The word 'deferred' appears 7 times on the page. It also appears in
> > the python-dev messages.
> >
> > If someone with more time and less bias then myself were to summarise
> > this discussion from 2006, I'd be most grateful, and they'd have
> > material for a great blog post.
> >
> > Finally, many thanks to Abe for finding this gem, and countless
> > people's hard work in keeping it alive to be found. Backwards
> > compatibility is there for a reason.
> >
> ___
> Python-ideas mailing list
> Python-ideas@python.org
> https://mail.python.org/mailman/listinfo/python-ideas
> Code of Conduct: http://python.org/psf/codeofconduct/
>
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] A simple proposal concerning lambda

2018-08-21 Thread MRAB

On 2018-08-22 01:25, Jonathan Fine wrote:

Hi Abe

Summary: You've done good work here. I've skim read the 2006
discussion you found.

You wrote:


I'm trying to dig up past threads about alternatives to lambda because I
would be astonished if "def" hadn't been considered and rejected for some
reason. What I've found so far is this unreassuring  post from Guido back in
2006



[Python-Dev] Let's just *keep* lambda
https://mail.python.org/pipermail/python-dev/2006-February/060415.html


This is an excellent piece of work. I'm most grateful. Here's what Guido said:


After so many attempts to come up with an alternative for lambda,
perhaps we should admit defeat. I've not had the time to follow the
most recent rounds, but I propose that we keep lambda, so as to stop
wasting everybody's talent and time on an impossible quest.


I've quickly read through the posts that followed Guido's message,
picked out the ones that interest me. Here's a list.


https://mail.python.org/pipermail/python-dev/2006-February/060487.html
https://mail.python.org/pipermail/python-dev/2006-February/060474.html
https://mail.python.org/pipermail/python-dev/2006-February/060471.html
https://mail.python.org/pipermail/python-dev/2006-February/060445.html
https://mail.python.org/pipermail/python-dev/2006-February/060435.html
https://mail.python.org/pipermail/python-dev/2006-February/060431.html
https://mail.python.org/pipermail/python-dev/2006-February/060470.html


And one of the messages had a link to still live and excellent page


https://wiki.python.org/moin/AlternateLambdaSyntax


This page lists over 100 suggestions, mostly variants. So far as I can
see, my simple proposal isn't listed on that page. The page also says


Hmm.

That lists:

def (a, b, c): return f(a) + o(b) - o(c)

and:

def (a, b, c) = f(a) + o(b) - o(c)

but not:

def (a, b, c): f(a) + o(b) - o(c)


**Definitely Desirable Features**

[snip]

*More friendly to inexperienced users*

[snip]

Compared to other Python keywords, 'lambda' is rather esoteric.
In the challenge for "farthest outside day-to-day English usage",
its closest competitor would probably be 'assert', as even 'def'
and 'elif' are just abbreviations for 'define' and 'else if'. Use of
simpler keywords may make deferred expressions appear less
intimidating than they seem with the current unusual keyword.


The word 'deferred' appears 7 times on the page. It also appears in
the python-dev messages.

If someone with more time and less bias then myself were to summarise
this discussion from 2006, I'd be most grateful, and they'd have
material for a great blog post.

Finally, many thanks to Abe for finding this gem, and countless
people's hard work in keeping it alive to be found. Backwards
compatibility is there for a reason.


___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] A simple proposal concerning lambda

2018-08-21 Thread Jonathan Fine
Hi Abe

Summary: You've done good work here. I've skim read the 2006
discussion you found.

You wrote:

> I'm trying to dig up past threads about alternatives to lambda because I
> would be astonished if "def" hadn't been considered and rejected for some
> reason. What I've found so far is this unreassuring  post from Guido back in
> 2006

> [Python-Dev] Let's just *keep* lambda
> https://mail.python.org/pipermail/python-dev/2006-February/060415.html

This is an excellent piece of work. I'm most grateful. Here's what Guido said:

> After so many attempts to come up with an alternative for lambda,
> perhaps we should admit defeat. I've not had the time to follow the
> most recent rounds, but I propose that we keep lambda, so as to stop
> wasting everybody's talent and time on an impossible quest.

I've quickly read through the posts that followed Guido's message,
picked out the ones that interest me. Here's a list.

> https://mail.python.org/pipermail/python-dev/2006-February/060487.html
> https://mail.python.org/pipermail/python-dev/2006-February/060474.html
> https://mail.python.org/pipermail/python-dev/2006-February/060471.html
> https://mail.python.org/pipermail/python-dev/2006-February/060445.html
> https://mail.python.org/pipermail/python-dev/2006-February/060435.html
> https://mail.python.org/pipermail/python-dev/2006-February/060431.html
> https://mail.python.org/pipermail/python-dev/2006-February/060470.html

And one of the messages had a link to still live and excellent page

> https://wiki.python.org/moin/AlternateLambdaSyntax

This page lists over 100 suggestions, mostly variants. So far as I can
see, my simple proposal isn't listed on that page. The page also says

> **Definitely Desirable Features**
[snip]
> *More friendly to inexperienced users*
[snip]
> Compared to other Python keywords, 'lambda' is rather esoteric.
> In the challenge for "farthest outside day-to-day English usage",
> its closest competitor would probably be 'assert', as even 'def'
> and 'elif' are just abbreviations for 'define' and 'else if'. Use of
> simpler keywords may make deferred expressions appear less
> intimidating than they seem with the current unusual keyword.

The word 'deferred' appears 7 times on the page. It also appears in
the python-dev messages.

If someone with more time and less bias then myself were to summarise
this discussion from 2006, I'd be most grateful, and they'd have
material for a great blog post.

Finally, many thanks to Abe for finding this gem, and countless
people's hard work in keeping it alive to be found. Backwards
compatibility is there for a reason.

-- 
Jonathan
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] A simple proposal concerning lambda

2018-08-21 Thread Abe Dillon
I'm trying to dig up past threads about alternatives to lambda because I
would be astonished if "def" hadn't been considered and rejected for some
reason. What I've found so far is this unreassuring  post from Guido back
in 2006



On Tue, Aug 21, 2018 at 4:27 PM, Jonathan Fine  wrote:

> Here's what I call a simple proposal. Some people might find it
> outrageous. Today is not 1st April.
>
>
> BACKGROUND
> 
> Many Python users don't like the name lambda. But many Python users
> don't want any change here. This is true because there are millions of
> Python users, and even 100 is many. And it's hard to introduce a new
> keyword, which might break existing code. (And perhaps even worse,
> break the community.)
>
> https://wiki.python.org/moin/LocalUserGroups
> > There about 1,637 Python user groups worldwide in almost 191 cities, 37
> countries and over 860,333 members.
>
>
> SOME VALID PYTHON
> ==
> Here's some valid Python, defining two functions fn and gn, that are
> virtually identical.
>
> >>> def fn(a, b=2, c=3):
> ... return a ** b / c
> >>> fn
> 
>
> >>> gn = lambda a, b=2, c=3: a ** b / c
> >>> gn
>  at 0x7ff815e2bbf8>
>
> Notice that fn and gn have the same type, and differ by name.
>
> >>> type(fn), type(gn)
> (, )
> >>> fn.__qualname__, gn.__qualname__
> ('fn', '')
>
> And that we can modify the display name of fn and gn.
>
> >>> fn.__qualname__ = 'my_fn'
> >>> fn
> 
>
> >>> gn.__qualname__ = 'my_gn'
> >>> gn
> 
>
>
> MY SIMPLE PROPOSAL
> 
>
> Here is my simple proposal. Enhance Python to allow
>
> >>> hn = def a, b=2, c=3: a ** b / c
> >>> hn
> 
> >>> hn.__qualname__
> ''
>
> MIGRATION
> ==
>
> Migration of code would require only a keyword substitution of
> 'lambda' by 'def'.
>
> And in the docs
> 1. Note that 'def' can mean 'define' (the current use), and also
> 'defer' (evaluation of an expression).
> 2. In the first case, we have a *named function*. In the second case,
> we have an *expression function*.
>
> This idea came to me while writing:
> https://mail.python.org/pipermail/python-ideas/2018-August/052880.html
>
> --
> Jonathan
> ___
> Python-ideas mailing list
> Python-ideas@python.org
> https://mail.python.org/mailman/listinfo/python-ideas
> Code of Conduct: http://python.org/psf/codeofconduct/
>
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Does jargon make learning more difficult?

2018-08-21 Thread Abe Dillon
[Chris Angelico]

> I have to defer to someone who knows in more detail here, but the
> parser will look ahead one "token", whatever a token is. (Technically
> it doesn't backtrack, it looks ahead - same difference.) In order for
> the ternary-if to work, the expression before the if has to be of a
> more restricted type than just "any expression" (for instance, you
> can't put a lambda function there, unless you parenthesize it).


Interesting. I really need to try delving into the nuts and bolts of Python.
I didn't know that about ternary expressions.

I don't know if you saw my recent discussion with Jonathan Fine, but he
brought up some good points too.
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Does jargon make learning more difficult?

2018-08-21 Thread Chris Angelico
On Wed, Aug 22, 2018 at 8:45 AM, Abe Dillon  wrote:
> [Chris Angelico]
>>
>> Python's parser is *deliberately* incapable of backtracking this far
>> in its definition of syntax.
>
>
> Can you explain how far the parser is capable of backtracking?
> It seems like  with  would require a similar amount
> of backtracking to ternary expressions:
>
>  if  else 
>
> If the preceding expression is the same in both cases, then the parser needs
> to backtrack just as far when it finds an "if" as when it finds a "with".

I have to defer to someone who knows in more detail here, but the
parser will look ahead one "token", whatever a token is. (Technically
it doesn't backtrack, it looks ahead - same difference.) In order for
the ternary-if to work, the expression before the if has to be of a
more restricted type than just "any expression" (for instance, you
can't put a lambda function there, unless you parenthesize it). But
I'm not fluent in all the details, and I definitely am not comfortable
citing exactly what the limits are. The last time I tried editing the
grammar, weird things happened.

ChrisA
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Does jargon make learning more difficult?

2018-08-21 Thread Abe Dillon
[Chris Angelico]

> Python's parser is *deliberately* incapable of backtracking this far
> in its definition of syntax.


Can you explain how far the parser is capable of backtracking?
It seems like  with  would require a similar amount
of backtracking to ternary expressions:

 if  else 

If the preceding expression is the same in both cases, then the parser
needs to backtrack just as far when it finds an "if" as when it finds a
"with".

[Chris Angelico]

> You then said that it was the parameter "key" that told you that
> this would be a function, which is also unacceptable in Python syntax.


That was *never* a statement about syntax. It was about the context clues a
reader has, not the parser. The proposed syntax:  with
 is an expression that evaluates to a function object regardless
of any parameter or any function it might or might not be passed to.

My argument is simply: Most cases where an anonymous function is more
expressive than a named function are also cases where, *from the
perspective of a human reading the code*, the signature is noisy preamble
that gets in the way of the expression.

In psuedo code, people tend to write things like:

>>> hand = sorted(cards, by=card.suit)

Obviously that wouldn't compile because the computer doesn't know what
"card" is. However;

>>> hand = sorted(cards, by=lambda card: card.suit)

puts a bunch of noise that's mostly of interest to the computer in front of
the expression that's of interest to the reader. There is precedent for
late-variable-binding in Python expressions already (e.g. comprehensions),
so it makes sense to me that the expression version of function declaration
could also bind the signature after the main expression.

The same logic follows for mappers, reducers, filters, callbacks,
event-handlers, etc.

[Chris Angelico]

> So how do you intend to do this?


I don't intend any of this to make its way into Python. It's a case study
of expression design. It's interesting to me to explore such alternatives.
It's fine to prod it and examine its flaws as Jonathan Fine has.

[Chris Angelico]

> And you still haven't done anything to show that this is actually
> better than "lambda card:"


I'm trying to, but I also have to answer all your misconceptions about the
idea (like that the syntax is function or parameter-dependent).

[Chris Angelico]

> I'm done.


OK. I'm sorry if I upset you.
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Off topic: 'strike a balance' - second language English

2018-08-21 Thread Jonathan Fine
Hi Greg

You (and a reddit user) wrote:

>> Matlab says: "Here, copy paste this and it'll work".

>> To the point that the workspace is designed to automatically strip >>>
>> from any copy and pasted commands.

> Maybe this is something Python's REPL should do?

Good idea.

Maybe this is something that you (or someone else) should raise on
bugs.python.org? And I expect that then, they'll ask for it to be
discussed on python-ideas.

So what do we get from the bounce? Well, you (or someone else) would
be keeping an eye on this. (Aside: I'd like to be the someone else,
but I don't have the time.).

-- 
Jonathan
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Does jargon make learning more difficult?

2018-08-21 Thread Abe Dillon
[Jonathan Fine]

> I have reservations about the name lambda. But there's a lot of
> code out there that uses lambda, and I'd like that code to continue to
> run.


Yes. I'm under no delusion that lambda will be replaced any time soon. Nor
do I believe any alternative I suggest will be enough of an improvement to
warrant breaking the "there should be one and only one obvious way to do
something rule". So I don't expect this conversation to lead to any change
to the language, I just think my case that it's sub-optimal might inform
future design decisions. Though it doesn't look like anyone finds it
especially convincing.

[Jonathan Fine]

> My understanding is that you prefer
> >>> EXPRESSION with IDEN
> to
> >>> lambda IDEN: EXPRESSION


Correct. My argument is two fold:

1) the name "lambda" is needlessly esoteric.
2) the format of lambdas is "backwards"

I tried to focus on the name gripe in this thread because trying to explain
both at the same time caused confusion. However, Stephen Turnbull's and
(more so) Steven D'Aprano's comments made the format argument semi-relevant
and I can't help getting on that soap-box...

[Jonathan Fine]

> How do you feel about this, as a means of defining an anonymous function?
> >>> with IDEN: EXPRESSION


I think it's better than lambda. I can't decide if I like it more than:

>>> def IDEN: EXPRESSION

Because def is more clearly connected to function declaration and i'm
somewhat sympathetic to the idea of expressionizing "with"-statements.
The only reason I don't prefer:

>>> EXPRESSION def IDEN

to

>>> EXPRESSION with IDEN

Is that it looks weird to me. It just doesn't seem right.

[Jonathan Fine]

> Now for a trick question. Consider
> >>> fn =  (lambda : EXPRESSION)
> This produces a function that has zero parameters.
> How would you write this, using 'with'. Would it be:
> >>> fn = (EXPRESSION with)
> I think this looks rather odd.


That's a good point. I hadn't considered that. There are several possible
formats that put the expression before the signature definition. The
specific form isn't quite as interesting to me. I would even prefer
something like:

>>> def (EXPRESSION [ SIG])

Mostly because "def" could then have a double meaning: "define" and
"deferred expression". I think that's kinda neat. My problem with putting
the signature first is that it usually amounts to noisy preamble that gets
in the way of the important code. In pseudo code you'd often write:

>>> hand = sorted(cards, by=card.suit)

But obviously the compiler doesn't know what "card" is since it's never
declared, so we write:

>>> hand = sorted(cards, by=lambda card: card.suit)

Notice that the information that's important to the reader: the expression,
is pushed behind information the computer needs but the reader probably
doesn't care about.
My claim is that in most cases, the signature is more noise than signal, so
it should come after the expression.

A function passed as a callback, key-function, mapper, reducer, filter,
event handler, etc. has a mostly pre-defined call signature. In most other
cases, you're better off using a named function.

Thanks for your input!

On Tue, Aug 21, 2018 at 3:51 PM, Jonathan Fine  wrote:

> Hi Abe
>
> First, I have reservations about the name lambda. But there's a lot of
> code out there that uses lambda, and I'd like that code to continue to
> run.
>
> You wrote:
> > func = value[card.suit] if card not in wilds else wild_value with card
>
> I thought I'd try this, and variants, in the Python interpreter. I got
>
> # An expression. It's valid syntax, get run-time error.
> >>> value[card.suit] if card not in wilds else wild_value
> NameError: name 'card' is not defined
>
> # An expression. It's valid syntax. Its value is a function. No run-time
> error.
> >>> lambda card: value[card.suit] if card not in wilds else wild_value
>  at 0x7ff815e2bbf8>
>
> # If Python were enhanced, an valid expression whose value is a function.
> >>> value[card.suit] if card not in wilds else wild_value with card
> SyntaxError: invalid syntax
>
> My understanding is that you prefer
> >>> EXPRESSION with IDEN
> to
> >>> lambda IDEN: EXPRESSION
>
> How do you feel about this, as a means of defining an anonymous function?
> >>> with IDEN: EXPRESSION
>
> We can't adopt it, of course, because it's already valid syntax, but
> with semantics.
>
> >>> with wibble:
> ...wobble
> NameError: name 'wibble' is not defined
>
> Now for a trick question. Consider
> >>> fn =  (lambda : EXPRESSION)
> This produces a function that has zero parameters.
>
> How would you write this, using 'with'. Would it be:
> >>> fn = (EXPRESSION with)
> I think this looks rather odd.
>
> --
> Jonathan
>
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Off topic: 'strike a balance' - second language English

2018-08-21 Thread Greg Ewing

Jonathan Fine wrote:

Matlab says: "Here, copy paste this and it'll work".

To the point that the workspace is designed to automatically strip >>>
from any copy and pasted commands.


Maybe this is something Python's REPL should do?

--
Greg
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] A simple proposal concerning lambda

2018-08-21 Thread Jonathan Fine
Here's what I call a simple proposal. Some people might find it
outrageous. Today is not 1st April.


BACKGROUND

Many Python users don't like the name lambda. But many Python users
don't want any change here. This is true because there are millions of
Python users, and even 100 is many. And it's hard to introduce a new
keyword, which might break existing code. (And perhaps even worse,
break the community.)

https://wiki.python.org/moin/LocalUserGroups
> There about 1,637 Python user groups worldwide in almost 191 cities, 37 
> countries and over 860,333 members.


SOME VALID PYTHON
==
Here's some valid Python, defining two functions fn and gn, that are
virtually identical.

>>> def fn(a, b=2, c=3):
... return a ** b / c
>>> fn


>>> gn = lambda a, b=2, c=3: a ** b / c
>>> gn
 at 0x7ff815e2bbf8>

Notice that fn and gn have the same type, and differ by name.

>>> type(fn), type(gn)
(, )
>>> fn.__qualname__, gn.__qualname__
('fn', '')

And that we can modify the display name of fn and gn.

>>> fn.__qualname__ = 'my_fn'
>>> fn


>>> gn.__qualname__ = 'my_gn'
>>> gn



MY SIMPLE PROPOSAL


Here is my simple proposal. Enhance Python to allow

>>> hn = def a, b=2, c=3: a ** b / c
>>> hn

>>> hn.__qualname__
''

MIGRATION
==

Migration of code would require only a keyword substitution of
'lambda' by 'def'.

And in the docs
1. Note that 'def' can mean 'define' (the current use), and also
'defer' (evaluation of an expression).
2. In the first case, we have a *named function*. In the second case,
we have an *expression function*.

This idea came to me while writing:
https://mail.python.org/pipermail/python-ideas/2018-August/052880.html

-- 
Jonathan
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Does jargon make learning more difficult?

2018-08-21 Thread Jonathan Fine
Hi Abe

First, I have reservations about the name lambda. But there's a lot of
code out there that uses lambda, and I'd like that code to continue to
run.

You wrote:
> func = value[card.suit] if card not in wilds else wild_value with card

I thought I'd try this, and variants, in the Python interpreter. I got

# An expression. It's valid syntax, get run-time error.
>>> value[card.suit] if card not in wilds else wild_value
NameError: name 'card' is not defined

# An expression. It's valid syntax. Its value is a function. No run-time error.
>>> lambda card: value[card.suit] if card not in wilds else wild_value
 at 0x7ff815e2bbf8>

# If Python were enhanced, an valid expression whose value is a function.
>>> value[card.suit] if card not in wilds else wild_value with card
SyntaxError: invalid syntax

My understanding is that you prefer
>>> EXPRESSION with IDEN
to
>>> lambda IDEN: EXPRESSION

How do you feel about this, as a means of defining an anonymous function?
>>> with IDEN: EXPRESSION

We can't adopt it, of course, because it's already valid syntax, but
with semantics.

>>> with wibble:
...wobble
NameError: name 'wibble' is not defined

Now for a trick question. Consider
>>> fn =  (lambda : EXPRESSION)
This produces a function that has zero parameters.

How would you write this, using 'with'. Would it be:
>>> fn = (EXPRESSION with)
I think this looks rather odd.

-- 
Jonathan
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Does jargon make learning more difficult?

2018-08-21 Thread Chris Angelico
On Wed, Aug 22, 2018 at 6:33 AM, Abe Dillon  wrote:
> [Chris Angelico]
>>
>> I use decks of cards primarily for non-game
>> usage (for instance, teaching data structures and algorithms - cards
>> laid out on a table can represent a tree, heap, array, etc)
>
>
> I do too. They're a great tool for visualizing and physically trying out
> different techniques.
>
> [Chris Angelico]
>>
>> A deck containing four suits of thirteen
>> cards plus one joker would have 53 cards, which is a prime number;
>> printing 54 cards lets you lay them out as 9 by 6 on a sheet, so it's
>> easy to add a second joker. Some decks (I have an Alice in Wonderland
>> themed deck) have *four* jokers.
>> As such, the most logical way to do this would be as an attribute of
>> the card.
>
>
> In most cases I've seen wild cards used, it's a declaration about a certain
> card (e.g. "Eights are wild."
> or "The 2 of clubs is wild."). I've found that if you're trying to model a
> game like poker or Monopoly, it's tempting to add complexity to simple
> objects, but it can lead to problems later on. A card doesn't know if it's
> wild. That's a function of the game being played. An ace may be high or low.

Well, okay. Then you should check if the card is a joker, rather than
checking if it's wild. That means your sort function is "by suit, and
within that by rank, but jokers are at the end" (ignoring wildness).

That said, though... I've seen and used a Canasta deck of cards, which
have game-specific information printed on them. Physical cards. So
there's precedent for that!

ChrisA
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Does jargon make learning more difficult?

2018-08-21 Thread Abe Dillon
[Chris Angelico]

> I use decks of cards primarily for non-game
> usage (for instance, teaching data structures and algorithms - cards
> laid out on a table can represent a tree, heap, array, etc)


I do too. They're a great tool for visualizing and physically trying out
different techniques.

[Chris Angelico]

> A deck containing four suits of thirteen
> cards plus one joker would have 53 cards, which is a prime number;
> printing 54 cards lets you lay them out as 9 by 6 on a sheet, so it's
> easy to add a second joker. Some decks (I have an Alice in Wonderland
> themed deck) have *four* jokers.
> As such, the most logical way to do this would be as an attribute of
> the card.


In most cases I've seen wild cards used, it's a declaration about a certain
card (e.g. "Eights are wild."
or "The 2 of clubs is wild."). I've found that if you're trying to model a
game like poker or Monopoly, it's tempting to add complexity to simple
objects, but it can lead to problems later on. A card doesn't know if it's
wild. That's a function of the game being played. An ace may be high or low.

On Tue, Aug 21, 2018 at 2:06 PM, Chris Angelico  wrote:

> On Wed, Aug 22, 2018 at 4:56 AM, Abe Dillon  wrote:
> > [Chris Angelico]
> >>
> >> In English, "card is not wild" can
> >> be interpreted as a membership check, but in Python, it is only an
> >> identity check; you're capitalizing on false readability by using this
> >> notation.
> >
> >
> > I promise that wasn't my intent. Since both my proposed form and the
> lambda
> > form use the same expression,
> > it doesn't really tip the balance in favor of my argument. Also, most toy
> > card problems I work with use a finite,
> > immutable set of cards, so identity checking isn't *that* weird.
>
> Fair enough. To be fair, I use decks of cards primarily for non-game
> usage (for instance, teaching data structures and algorithms - cards
> laid out on a table can represent a tree, heap, array, etc), and my
> decks of cards are artistic. A deck containing four suits of thirteen
> cards plus one joker would have 53 cards, which is a prime number;
> printing 54 cards lets you lay them out as 9 by 6 on a sheet, so it's
> easy to add a second joker. Some decks (I have an Alice in Wonderland
> themed deck) have *four* jokers.
>
> As such, the most logical way to do this would be as an attribute of
> the card. Its jokerness is as much a feature as the clubness of
> another card. You can pick up a physical card, look at it, and say
> "This is a joker"; you don't have to see if it's in a list of specific
> known jokers.
>
> hand = sorted(cards, by=value[card.suit] if not card.wild else
> max_value with card)
>
> Honestly, though, it'd usually be more interesting to sort by rank
> within suit. What you're doing here would group the cards by suit,
> ignoring their ranks; more useful would be:
>
> hand = sorted(cards, key=lambda card: (card.is_wild, card.suit, card.rank))
>
> Much cleaner. No conditionals needed.
>
> ChrisA
> ___
> Python-ideas mailing list
> Python-ideas@python.org
> https://mail.python.org/mailman/listinfo/python-ideas
> Code of Conduct: http://python.org/psf/codeofconduct/
>
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Does jargon make learning more difficult?

2018-08-21 Thread Chris Angelico
On Wed, Aug 22, 2018 at 6:24 AM, Abe Dillon  wrote:
> [Chris Angelico]
>>
>> That right there is unacceptable. You should not have to know the
>> destination to understand what something fundamentally is.
>
>
> You don't *have* to know what the parameter "key" is to know that
> (value[card.suit] ... with card) is a function. You can identify that it's a
> function just by reading the full expression. However, if you don't know
> what "key" is, then it'll cause far more confusion than the late declaration
> of the function's parameters.
>
> [Chris Angelico]
>>
>> You can't redefine language syntax based on the function being called.
>
>
> That's not at all what I suggested. You were walking through my example from
> the reader's perspective. I was explaining how the reader will often have
> plenty of context about what they're reading before they get to the
> signature declaration. Whether it be because they know what the "key"
> parameter means or because they know "card" is undeclared or both. I never
> claimed the language syntax should be based on the function being called.
>
> func = value[card.suit] if card not in wilds else wild_value with card
>
> Works independent of the function being called. It's just not a common use
> case because it obviates the expressiveness of anonymous functions. You
> might as well use a "def" statement.

Python's parser is *deliberately* incapable of backtracking this far
in its definition of syntax. So if you want to have something where
the first long slab of it is entirely acceptable as an expression,
right up until you get to the "with" at the end, it's not going to
work. You then said that it was the parameter "key" that told you that
this would be a function, which is also unacceptable in Python syntax.
So how do you intend to do this?

And you still haven't done anything to show that this is actually
better than "lambda card:" at the beginning. I'm done.

ChrisA
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Does jargon make learning more difficult?

2018-08-21 Thread Abe Dillon
[Chris Angelico]

> That right there is unacceptable. You should not have to know the
> destination to understand what something fundamentally is.


You don't *have* to know what the parameter "key" is to know that
(value[card.suit] ... with card) is a function. You can identify that it's
a function just by reading the full expression. However, if you don't know
what "key" is, then it'll cause far more confusion than the late
declaration of the function's parameters.

[Chris Angelico]

> You can't redefine language syntax based on the function being called.


That's not at all what I suggested. You were walking through my example
from the reader's perspective. I was explaining how the reader will often
have plenty of context about what they're reading before they get to the
signature declaration. Whether it be because they know what the "key"
parameter means or because they know "card" is undeclared or both. I never
claimed the language syntax should be based on the function being called.

func = value[card.suit] if card not in wilds else wild_value with card

Works independent of the function being called. It's just not a common use
case because it obviates the expressiveness of anonymous functions. You
might as well use a "def" statement.

The thing that makes callbacks difficult is not knowing how they're called.
I tried to throw a little JavaScript into my curriculum once thinking "how
bad can it be?" and suggested my students work on a project using the Force
Directed Graph from D3.js . That was
a HUGE mistake not because anonymous functions are confusing but because
the example (at the time) had no documentation at all (like this one
) and used mysterious callbacks
everywhere. The main documentation for D3.js is super difficult to
navigate, when all you want to do is slightly modify one of the examples
(use svg images for the nodes and have stats display "on mouse over").

If you don't know what "".join() does, then you're going to have trouble
making sense of:

def initials(person):
 return "".join(name[0] + "." for name in person.names if name)

The late assignment of the name variable will NOT be your main source of
confusion. If you do know what "".join() does, then it should take you much
less context to realize you're reading a generator expression. By the time
you read the yet-to-be-assigned "name" variable you should be tipped off.

On Tue, Aug 21, 2018 at 1:58 PM, Chris Angelico  wrote:

> On Wed, Aug 22, 2018 at 4:56 AM, Abe Dillon  wrote:
> > [Chris Angelico]
> >>
> >> Okay, let's read that.
> >> hand = # we're assigning this to the name 'hand'
> >> sorted( # calling the function named 'sorted'
> >> cards, # positional argument, whatever's in the 'cards' variable
> >> by= # keyword argument, what comes next is the 'by' argument
> >> value[card.suit] # subscript 'value' with 'card.suit'
> >> if card is not wild # yep
> >> else max_value # so we have an alternative
> >> with card # WAIT WAIT WAIT
> >> Once you get to 'with card', you have to go back and completely
> >> reinterpret everything prior to that as a function.
> >
> >
> > The revelation that it's a function should come when you read the "by" or
> > "key". If you don't know what that parameter is, then that's where the
> "wait
> > wait wiat!" should happen.
>
> That right there is unacceptable. You should not have to know the
> destination to understand what something fundamentally is. You can't
> redefine language syntax based on the function being called.
>
> ChrisA
> ___
> Python-ideas mailing list
> Python-ideas@python.org
> https://mail.python.org/mailman/listinfo/python-ideas
> Code of Conduct: http://python.org/psf/codeofconduct/
>
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Jump to function as an an alternative to call function

2018-08-21 Thread Kirill Balunov
пн, 20 авг. 2018 г. в 17:23, Steven D'Aprano :

> On Sun, Aug 19, 2018 at 06:18:56PM +0300, Kirill Balunov wrote:
> [...]
> [Kirill]
> > Let me disagree with you. While CPython is only one of the
> implementations
> > of the Python language, it is the most common one and defacto is
> considered
> > as a standard.
>
> Not in this case. If CPython intended this to be the language behaviour,
> it should specify that limitation instead of merely giving a doc warning
> that changes "may not" affect the local variables.
>
> In fact, the warning in the docs is too strong. Modifying locals()
> inside a class or module scope is allowed, and works fine. It is only
> functions which is problematic.
>
>
I think I was pretty clear, that I only spoke about `locals` behavior
inside functions and all its derivatives. At least I tried :) Talking about
class and module, as for me, modifying `locals()`
inside a class or module scope is allowed but is far from the right way to
do.

The phrase `may not affect` is the worst phrase for deterministic system.
Your program may work or may not work correctly depending on the underlying
Python implementation, but you would not know about this because there will
be no error and no warning. Good luck fixing such bugs.


>
> > Therefore, all the others, to be compliant, try to replicate
> > all subtleties and features of the basic implementation - CPython.
>
> Implementations are expected to obey the documented behaviour (unless
> given special dispensation to break the rules, which I think has
> happened once or twice with MicroPython). For behaviour which isn't
> dpcumented, it is true that implementations *often* try to copy CPython,
> but that's not mandatory and there are exceptions.
>
>
I think you are talking about recent discussion of MicroPython's `dict`
implementation (that the order is not guaranteed?) It is a necessary trade
off for them given their niche (if I understand correctly the explanation
given by Paul Sokolovsky).


> [...]
>
> Users of CPython frequently rely on CPython implementation details. Why
> do you think Jython and IronPython users will be different?
>
>
Hmm, what do you mean? It seems to me that everything happens the other way
round. For example, recent attempts of numpy to make numpy more PyPy
friendly. In fact, I do not know anyone who specifically rely on CPython
implementation details in their production code.

with kind regards,
-gdg
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Does jargon make learning more difficult?

2018-08-21 Thread Chris Angelico
On Wed, Aug 22, 2018 at 4:56 AM, Abe Dillon  wrote:
> [Chris Angelico]
>>
>> In English, "card is not wild" can
>> be interpreted as a membership check, but in Python, it is only an
>> identity check; you're capitalizing on false readability by using this
>> notation.
>
>
> I promise that wasn't my intent. Since both my proposed form and the lambda
> form use the same expression,
> it doesn't really tip the balance in favor of my argument. Also, most toy
> card problems I work with use a finite,
> immutable set of cards, so identity checking isn't *that* weird.

Fair enough. To be fair, I use decks of cards primarily for non-game
usage (for instance, teaching data structures and algorithms - cards
laid out on a table can represent a tree, heap, array, etc), and my
decks of cards are artistic. A deck containing four suits of thirteen
cards plus one joker would have 53 cards, which is a prime number;
printing 54 cards lets you lay them out as 9 by 6 on a sheet, so it's
easy to add a second joker. Some decks (I have an Alice in Wonderland
themed deck) have *four* jokers.

As such, the most logical way to do this would be as an attribute of
the card. Its jokerness is as much a feature as the clubness of
another card. You can pick up a physical card, look at it, and say
"This is a joker"; you don't have to see if it's in a list of specific
known jokers.

hand = sorted(cards, by=value[card.suit] if not card.wild else
max_value with card)

Honestly, though, it'd usually be more interesting to sort by rank
within suit. What you're doing here would group the cards by suit,
ignoring their ranks; more useful would be:

hand = sorted(cards, key=lambda card: (card.is_wild, card.suit, card.rank))

Much cleaner. No conditionals needed.

ChrisA
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Does jargon make learning more difficult?

2018-08-21 Thread Abe Dillon
[Chris Angelico]

> Okay, let's read that.
> hand = # we're assigning this to the name 'hand'
> sorted( # calling the function named 'sorted'
> cards, # positional argument, whatever's in the 'cards' variable
> by= # keyword argument, what comes next is the 'by' argument
> value[card.suit] # subscript 'value' with 'card.suit'
> if card is not wild # yep
> else max_value # so we have an alternative
> with card # WAIT WAIT WAIT
> Once you get to 'with card', you have to go back and completely
> reinterpret everything prior to that as a function.


The revelation that it's a function should come when you read the "by" or
"key". If you don't know what that parameter is, then that's where the
"wait wait wiat!" should happen. Then type "help(sorted)" in a console or
something. Another hint can come from the appearance of an undeclared
variable: card. (I know, I know: I didn't declare several variables, just
imagine that 'card' is the only variable not previously declared).

It's no more surprising than reading a comprehension:

initials = {person.name[0] for person in people if person.name}

initials = # we're assigning this to the name "initials"
initials = { # it's a dictionary or set of something
initials = { person.name[0]  # I'v never seen "person" before, this must be
a comprehension or something
 # anyway, no ":" means it's a set of the first
letter of each person's name
intiials = { person.name[0] for person # WAIT WAIT WIAT WHAT?!? Just
kidding, I saw this coming...

[Chris Angelico]

> > Oh wait... Did I accidentally replace "key" with "by"? Huh... It seems to
> > make more sense even though the jargon is a "key function"... Oops! ;)
> I'm sure it would make even more sense if you wrote it this way:
> hand = sorted(cards, by="suit")
> That's how SQL works - you just name the column that you want to order
> the results by. But if you think "by" is a better keyword here, start
> explaining why your ordering is done with an anonymous function, not
> with an attribute name.


If the logic is simple enough, you can just use a reference to the method
from the class:

hand = sorted(cards, by=Card.suit)  # where Card is the class

That's why I tend to use a more complex example. Otherwise the lambda isn't
really justified.

[Chris Angelico]

> JFTR, I wouldn't implement a deck of cards this way.


I don't implement decks of cards often, but in toy problems; I find just
using 2-character strings works fine:

Ace_of_spades = "As"
Ten_of_hearts = "Th"
etc...

That can easily be extended by a named tuple initialized with unpacking:

Card = namedtuple("Card", "rank suit")
Ace_of_spades = Card(*"As")

[Chris Angelico]

> It implies that there is exactly one wild card, where many
> decks of cards have at least two.


I don't know of many games that have wild cards, but that's a simple remedy:

hand = sorted(cards, by=value[card.suit] if card not in wilds else
max_value with card)

[Chris Angelico]

> In English, "card is not wild" can
> be interpreted as a membership check, but in Python, it is only an
> identity check; you're capitalizing on false readability by using this
> notation.


I promise that wasn't my intent. Since both my proposed form and the lambda
form use the same expression,
it doesn't really tip the balance in favor of my argument. Also, most toy
card problems I work with use a finite,
immutable set of cards, so identity checking isn't *that* weird.

On Tue, Aug 21, 2018 at 1:12 PM, Chris Angelico  wrote:

> On Wed, Aug 22, 2018 at 3:56 AM, Abe Dillon  wrote:
> > I've never hears someone say, "My child's name will be if it's a girl
> Sally
> > otherwise Billy."
>
> "My child's name depends on gender - if it's a girl, Sally, otherwise
> Billy." Seems fine to me. You can always come up with something
> awkward in a particular order, but it's not the order that made it
> awkward.
>
> > Consider the alternate form:  with   (thought there are
> > many alternative possibilities)
> >
> > hand = sorted(cards, key=lambda card: value[card.suit] if card is not
> wild
> > else max_value)
> >
> > hand = sorted(cards, by=value[card.suit] if card is not wild else
> > max_value with card)
> >
> > # notice how unsurprising it is that the signature is "card"
>
> Okay, let's read that.
>
> hand = # we're assigning this to the name 'hand'
> sorted( # calling the function named 'sorted'
> cards, # positional argument, whatever's in the 'cards' variable
> by= # keyword argument, what comes next is the 'by' argument
> value[card.suit] # subscript 'value' with 'card.suit'
> if card is not wild # yep
> else max_value # so we have an alternative
> with card # WAIT WAIT WAIT
>
> Once you get to 'with card', you have to go back and completely
> reinterpret everything prior to that as a function. You have to scan
> back and go "hang on, so exactly how much of this is getting wrapped
> up into a function here?". Contrast the Python version:
>
> hand = sorted(cards, key=lambda card: 

Re: [Python-ideas] Off topic: 'strike a balance' - second language English

2018-08-21 Thread Jonathan Fine
I wrote:

> No mention here, or elsewhere on the page, that  [>>>] at the top
> right of a code example toggles the presence or absence of prompts.

Now raised, and cross-referenced as an issue.
https://bugs.python.org/issue34451
docs: tutorial/introduction doesn't mention toggle of prompts

Perhaps discussion of this should move there.

-- 
Jonathan
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Off topic: 'strike a balance' - second language English

2018-08-21 Thread Jonathan Fine
Hi Steve

You wrote:

> I would just like to point out that the ipython %paste magic very
> handily strips leading >, ... & + characters from the pasted block,
> (there is also some clever dedenting done).

[useful example, snipped]

> Which is ideal. I personally find that many beginners get on a lot
> better in the iPython console than in the python one.

Thank you very much for this. I didn't know about this solution to the
problem. Docs search for ipython brings up

https://docs.python.org/3/tutorial/interactive.html

One alternative enhanced interactive interpreter that has been around
for quite some time is IPython, which features tab completion, object
exploration and advanced history management. It can also be thoroughly
customized and embedded into other applications. Another similar
enhanced interactive environment is bpython.


I've now played a little with (both look nice):
> https://www.bpython-interpreter.org
> https://repl.it/repls/LightcoralMoralDistributedcomputing

Perhaps beginners would benefit from something better than the
default, but simpler than ipython. But I don't have any experience to
support this view. There's related prior art in the well-regarded
https://codewith.mu/en/about. (Steve, I'd welcome your comments on
this.)

So thank you for bringing iPython's nifty %paste trick to my (and the
thread's) attention.

-- 
Jonathan
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Off topic: 'strike a balance' - second language English

2018-08-21 Thread Jonathan Fine
Chris Angelico wrote

> Where in the linked-to What's New page is there an example of that?
> There are several code blocks that ARE copy/pasteable, even into the
> vanilla interpreter.

Good question. The reddit user wrote.


https://www.reddit.com/r/Python/comments/70myto/whats_new_in_python_37_python_370a0_documentation/dn4zd20/
Take this example for re.sub. [https://docs.python.org/3/library/re.html#re.sub]

Trying that out requires 3 separate copy and pastes just to do one
example. Or you have to put it in an intermediate file, clean it up
then paste it in. The examples are also grouped by sub function not by
what they do.


I think the problem is the user didn't see the [>>>] toggle at the top
right of the code block. I know I didn't just now, when I tried it
just now. It was only the strength of your assertion, Chris, that made
me go back and try again.


https://docs.python.org/3/tutorial/introduction.html

In the following examples, input and output are distinguished by the
presence or absence of prompts (>>> and …): to repeat the example, you
must type everything after the prompt, when the prompt appears; lines
that do not begin with a prompt are output from the interpreter. Note
that a secondary prompt on a line by itself in an example means you
must type a blank line; this is used to end a multi-line command.


No mention here, or elsewhere on the page, that  [>>>] at the top
right of a code example toggles the presence or absence of prompts.

-- 
Jonathan
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Off topic: 'strike a balance' - second language English

2018-08-21 Thread Chris Angelico
On Wed, Aug 22, 2018 at 2:55 AM, Jonathan Fine  wrote:
> Nick Loadholtes wrote (elsewhere, quoted in this thread - by me).
>
>> Make your docs work as hard as your code does. Clear examples will
>> make your code stand out in a good way.
>
> With a bit more searching I found:
> 
> https://www.reddit.com/r/Python/comments/70myto/whats_new_in_python_37_python_370a0_documentation/dn4v667/
>
> I'll disagree. Nothing is better than Mathworks documentation. I like
> documentation by example.
>
> Python gives you the dry, technically correct verbiage behind how
> something works.
>
> Matlab says: "Here, copy paste this and it'll work".
>
> To the point that the workspace is designed to automatically strip >>>
> from any copy and pasted commands.
>
> Even with most Python examples you can't just copy and paste a chunk
> of an example from the web or documentation because you need to clean
> off >>> first.
> 

Where in the linked-to What's New page is there an example of that?
There are several code blocks that ARE copy/pasteable, even into the
vanilla interpreter.

ChrisA
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Does jargon make learning more difficult?

2018-08-21 Thread Chris Angelico
On Wed, Aug 22, 2018 at 3:56 AM, Abe Dillon  wrote:
> I've never hears someone say, "My child's name will be if it's a girl Sally
> otherwise Billy."

"My child's name depends on gender - if it's a girl, Sally, otherwise
Billy." Seems fine to me. You can always come up with something
awkward in a particular order, but it's not the order that made it
awkward.

> Consider the alternate form:  with   (thought there are
> many alternative possibilities)
>
> hand = sorted(cards, key=lambda card: value[card.suit] if card is not wild
> else max_value)
>
> hand = sorted(cards, by=value[card.suit] if card is not wild else
> max_value with card)
>
> # notice how unsurprising it is that the signature is "card"

Okay, let's read that.

hand = # we're assigning this to the name 'hand'
sorted( # calling the function named 'sorted'
cards, # positional argument, whatever's in the 'cards' variable
by= # keyword argument, what comes next is the 'by' argument
value[card.suit] # subscript 'value' with 'card.suit'
if card is not wild # yep
else max_value # so we have an alternative
with card # WAIT WAIT WAIT

Once you get to 'with card', you have to go back and completely
reinterpret everything prior to that as a function. You have to scan
back and go "hang on, so exactly how much of this is getting wrapped
up into a function here?". Contrast the Python version:

hand = sorted(cards, key=lambda card: value[card.suit] if card is not
wild else max_value)

hand = # we're assigning this to the name 'hand'
sorted( # calling the function named 'sorted'
cards, # positional argument, whatever's in the 'cards' variable
key= # keyword argument, what comes next is the 'key' argument
lambda card: # a function taking one argument
value[card.suit] # subscript 'value' with 'card.suit'
if card is not wild # yep
else max_value # so we have an alternative
) # and we're done

The only part where you have to back up and change your interpretation
is when you hit "if card is not wild", which reads well enough to
justify the odd ordering. (JFTR, I wouldn't implement a deck of cards
this way. It implies that there is exactly one wild card, where many
decks of cards have at least two. In English, "card is not wild" can
be interpreted as a membership check, but in Python, it is only an
identity check; you're capitalizing on false readability by using this
notation.)

> Oh wait... Did I accidentally replace "key" with "by"? Huh... It seems to
> make more sense even though the jargon is a "key function"... Oops! ;)

I'm sure it would make even more sense if you wrote it this way:

hand = sorted(cards, by="suit")

That's how SQL works - you just name the column that you want to order
the results by. But if you think "by" is a better keyword here, start
explaining why your ordering is done with an anonymous function, not
with an attribute name.

ChrisA
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Does jargon make learning more difficult?

2018-08-21 Thread Abe Dillon
[Stephen Turnbull]

> I was an economist then, and I'm an economist still, but I met lambda
> in 1977.  Surely lambda has had that role in computer languages since
> shortly before I was born.


According to Wikipedia  Lisp
was the first language to use anonymous functions (introduced in 1958).

[Stephen Turnbull]

> I would guess anybody above a certain age
> would reach for "lambda" first for a keyword to denote or define an
> anonymous function.  Not because of the lambda calculus, but because
> of Lisp.


Wikipedia lists the anonymous function syntax of 40+ languages
 and only 5
(Lisp, Scheme, Python, Ruby, and Maxima) use the "lambda" keyword.
Haskel uses a "\" which I'm pretty sure is supposed to look like the lambda
symbol, but even that syntax seems unpopular too.

[Stephen Turnbull]

> Maybe there's a better word than "regret".  After all, It's
> hard to see how you could prototype range better than "range([START,]
> END, [STRIDE])", and the same might be true for "def [NAME] ([ARG0,]
> ...):".


I wasn't aware that Guido considered "range" to be warty. I like the way it
mimics slicing syntax. It makes it easy for me to remember. It seems like a
very pragmatic design.

[Steven D'Aprano]

> Secure in the knowledge that Guido probably isn't reading this and won't
> contradict me *wink* I'm going to try channelling him.


SUMMON THE GREAT CREATOR!

I wonder if I say his name three times...
Guido Van Rossum! Guido Van Rossum! Guido Van Rossum!

[Steven D'Aprano]

> I think he would regret "def expressions", but not because of the range
> reason.

I think its because he likes the relatively strict demarcation between
statements
> and expressions.
> We have 4 statements that have a expression form:
> if...else versus ternary if expressions;
> for loops versus comprehensions;
> (soon) = assignment versus := assignment expressions; and
> def versus lambda.


(I don't know why Gmail's quotes screw up formatting...)

I don't think that's the reason those expressions have different formats
than their statement counterparts.
Expressions allow for more flexible arrangement than expressions because
the order of execution of an expression doesn't have to follow the order of
declaration.
While it's more natural to say "do something to each item in this
collection that meets some condition" you can't access variables before
they're declared in statements
so you have to tell the computer explicitly that you're looping over some
iterable first. Expressions allow you to be more expressive.

You don't have to put your edge-case checking up-front and in the way. When
99.9% of the time you just want:

x = y

you can shove the edge-case checking to the side and let the core logic
shine:

x = y   if not edge_case else special_value

# extra spaces added for emphasis

besides:

result = if condition expression else expression

is super awkward to read out loud. That's not how I think at least.
I've never hears someone say, "My child's name will be if it's a girl Sally
otherwise Billy."

All of the expressions use either the same or similar keywords or symbols
*except* def and lambda.

func = def : 

Is about as different from the statement form as "x := y" is from "x = y".
No name, no parentheses for the arguments.
Finally, I know you've heard the other half of my anti-lambda manifest, but
I don't know if Stephen Turnbull has, so I'll briefly present it again.

It's not just the name "lambda" that bothers me, it's the arrangement of
the logic and signature. I believe that the expressiveness that allows
comprehensions to put the core logic in front of the less important (for
readability) loop and filtering constructs, anonymous functions could have
been arranged to put the logic in front of the (almost always) less
important signature. The reason I say the signature is almost always less
important is because one almost always uses an anonymous functions as an
argument (key-function, callback, map, reduce, filter, etc.) to something
that already defines the call signature it expects.

Consider the alternate form:  with   (thought there are
many alternative possibilities)

hand = sorted(cards, key=lambda card: value[card.suit] if card is not wild
else max_value)

hand = sorted(cards, by=value[card.suit] if card is not wild else
max_value with card)

# notice how unsurprising it is that the signature is "card"

Oh wait... Did I accidentally replace "key" with "by"? Huh... It seems to
make more sense even though the jargon is a "key function"... Oops! ;)

Note: if this were a full proposal, lambdas with complex arguments or in
certain situations would require parens: ( with )

On Tue, Aug 21, 2018 at 9:31 AM, Steven D'Aprano 
wrote:

> On Tue, Aug 21, 2018 at 02:07:33PM +0900, Stephen J. Turnbull wrote:
>
> > I was an economist then, and I'm an economist still, but I met lambda
> > in 1977.  Surely lambda has had 

Re: [Python-ideas] Off topic: 'strike a balance' - second language English

2018-08-21 Thread Steve Barnes



On 21/08/2018 17:55, Jonathan Fine wrote:
> Nick Loadholtes wrote (elsewhere, quoted in this thread - by me).
> 
>> Make your docs work as hard as your code does. Clear examples will
>> make your code stand out in a good way.
> 
> With a bit more searching I found:
> 
> https://www.reddit.com/r/Python/comments/70myto/whats_new_in_python_37_python_370a0_documentation/dn4v667/
> 
> I'll disagree. Nothing is better than Mathworks documentation. I like
> documentation by example.
> 
> Python gives you the dry, technically correct verbiage behind how
> something works.
> 
> Matlab says: "Here, copy paste this and it'll work".
> 
> To the point that the workspace is designed to automatically strip >>>
> from any copy and pasted commands.
> 
> Even with most Python examples you can't just copy and paste a chunk
> of an example from the web or documentation because you need to clean
> off >>> first.
> 
> 
> It did me good, to read the resulting discussion on reddit.
> 

I would just like to point out that the ipython %paste magic very 
handily strips leading >, ... & + characters from the pasted block, 
(there is also some clever dedenting done).

So taking the example code:
 >>> def fn(param):
... """ Print the param """
... print(param)
...
 >>> fn(6)

on the clipboard and in ipython entering %paste results in:


In [2]: %paste
 >>> def fn(param):
... """ Print the param """
... print(param)
...
 >>> fn(6)

## -- End pasted text --
6

Which is ideal. I personally find that many beginners get on a lot 
better in the iPython console than in the python one.
-- 
Steve (Gadget) Barnes
Any opinions in this message are my personal opinions and do not reflect 
those of my employer.

---
This email has been checked for viruses by AVG.
https://www.avg.com

___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Off topic: 'strike a balance' - second language English

2018-08-21 Thread Jonathan Fine
Nick Loadholtes wrote (elsewhere, quoted in this thread - by me).

> Make your docs work as hard as your code does. Clear examples will
> make your code stand out in a good way.

With a bit more searching I found:

https://www.reddit.com/r/Python/comments/70myto/whats_new_in_python_37_python_370a0_documentation/dn4v667/

I'll disagree. Nothing is better than Mathworks documentation. I like
documentation by example.

Python gives you the dry, technically correct verbiage behind how
something works.

Matlab says: "Here, copy paste this and it'll work".

To the point that the workspace is designed to automatically strip >>>
from any copy and pasted commands.

Even with most Python examples you can't just copy and paste a chunk
of an example from the web or documentation because you need to clean
off >>> first.


It did me good, to read the resulting discussion on reddit.

-- 
Jonathan
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Does jargon make learning more difficult?

2018-08-21 Thread Steven D'Aprano
On Tue, Aug 21, 2018 at 02:07:33PM +0900, Stephen J. Turnbull wrote:

> I was an economist then, and I'm an economist still, but I met lambda
> in 1977.  Surely lambda has had that role in computer languages since
> shortly before I was born.  I would guess anybody above a certain age
> would reach for "lambda" first for a keyword to denote or define an
> anonymous function.  Not because of the lambda calculus, but because
> of Lisp.  (OK, that's indirectly because of the lambda calculus.)

Its pretty much a term of art.

(Aside: "term of art" is itself a term of art:
https://legal-dictionary.thefreedictionary.com/Term+of+Art )


I think that complaining about lambda is like complaining about "3-sigma 
versus 6-sigma processes" in process management. (Not computer 
processes, manufacturing processes and quality control.) Or for that 
matter, "mean" and "standard deviation" in statistics.

The main difference is that most people are introduced to mean and stdev 
in secondary school, while functional programming idioms and lambda are 
generally stumbled across in the field. (I know that's how I learned of 
the term: through Python.)


> Had Guido decided to change it to "def", I suspect he'd be regretting
> it slightly today, for reasons similar to the regrets about "range":
> we normally only allow omitting positional arguments at the end of the
> list.  Maybe there's a better word than "regret".  After all, It's
> hard to see how you could prototype range better than "range([START,]
> END, [STRIDE])", and the same might be true for "def [NAME] ([ARG0,]
> ...):".

Secure in the knowledge that Guido probably isn't reading this and won't 
contradict me *wink* I'm going to try channelling him. I think he would 
regret "def expressions", but not because of the range reason. I think 
its because he likes the relatively strict demarcation between 
statements and expressions.

We have 4 statements that have a expression form:

if...else versus ternary if expressions;

for loops versus comprehensions;

(soon) = assignment versus := assignment expressions; and

def versus lambda.

(Did I miss any? I don't include technicalities like dot attribute 
access versus getattr and similar.) It's notable that in none of those 
cases the syntax is quite the same in the two forms. There's always 
enough differentiation between the statement and expression that there's 
never any ambiguity which is intended. We don't have:

result = if condition expression else expression

where it is the lack of colons which hints that it is an expression, we 
have a completely different syntax. So I think Guido probably wouldn't 
like the idea of using def in expressions:

def function(arg, callback=def: None):
pass


That's my guess, for what it's worth.



-- 
Steve
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Off topic: 'strike a balance' - second language English

2018-08-21 Thread Jonathan Fine
Hi

Earlier today, I did a search for 'documentation by example python' and found

Example of great documentation in Python: Nick Loadholtes (copied)
https://ironboundsoftware.com/blog/2017/12/11/great-documentation-python/

The example is:
https://docs.python.org/3/library/random.html#examples-and-recipes

So who to thank: Here's the history of the source for the doc page.
https://github.com/python/cpython/commits/3.7/Doc/library/random.rst

I don't have time right now to look at all the history. But most of
the recent commits are from Raymond Hettinger.

I'll give Nick's web page the last word.


Make your docs work as hard as your code does. Clear examples will
make your code stand out in a good way. Great documentation is out
there, lets make more of it. Here’s what you need to create:

* A plain language explanation of what your library does
* The shortest possible code example
* A quick list of any common issues
* Links to where you can learn more details

If you can create that for your code, you are doing a great service to us all.


-- 
Jonathan
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Pre-conditions and post-conditions

2018-08-21 Thread Paul Moore
On Tue, 21 Aug 2018 at 11:27, Steven D'Aprano  wrote:
>
> On Tue, Aug 21, 2018 at 09:06:54AM +0200, Marko Ristin-Kaufmann wrote:
>
> > Is there any chance to introduce these constructs in the language or is it
> > too small a feature for such a big change?
>
> I don't think contracts is a small feature. I think it is a HUGE
> feature, but under-appreciated by most developers. (Probably due to
> unfamiliarity, and the difficulty in using it in a language with no
> syntactic support.)

Agreed. And it sounds like there are a lot of subtleties to contracts
that I certainly hadn't appreciated (I don't know if the same is true
of others). For example,

On Tue, 21 Aug 2018 at 08:08, Marko Ristin-Kaufmann
 wrote:
>
> I think that these objections miss what actually Daniel Moisset wrote in his 
> message: contracts are more than pre- and post-condition checks on a 
> function. The inheritance of decorators does not imply just inheriting the 
> pre- and post-conditions, but also relaxing and tightening them (represented 
> by "require else" and "ensure then" in Eiffel). If this is to be used 
> effectively in practice with little overhead then we would either need to 
> introduce new syntax to the language or make the compiler improve the byte 
> code on the fly.

I've no idea what "relaxing" and "tightening" of contracts involves,
or how it would translate into Python. So I'd imagine that in order to
put together a proposal for adding contracts to Python, you'd need to
explain what contracts are, and how they work, to get past people's
preconceptions that "they are just assertions". Otherwise, it's likely
to be hard to persuade people of the benefits.

Personally, I don't really think I can comment much further, precisely
because it looks like I don't know enough about what contracts are and
how they'd be used to contribute :-)

Paul
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Pre-conditions and post-conditions

2018-08-21 Thread INADA Naoki
On Thu, Aug 16, 2018 at 4:19 PM Elazar  wrote:
>
> You might also be interested in pep-563. although it is not intended for 
> design by contract, it can help (syntactically).
>

FYI, PEP 563 doesn't help it.

Read this section:
https://www.python.org/dev/peps/pep-0563/#non-typing-usage-of-annotations

"With this in mind, uses for annotations incompatible with the
aforementioned PEPs should be considered deprecated."

-- 
INADA Naoki  
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Pre-conditions and post-conditions

2018-08-21 Thread Steven D'Aprano
On Tue, Aug 21, 2018 at 09:06:54AM +0200, Marko Ristin-Kaufmann wrote:

> Is there any chance to introduce these constructs in the language or is it
> too small a feature for such a big change?

I don't think contracts is a small feature. I think it is a HUGE 
feature, but under-appreciated by most developers. (Probably due to 
unfamiliarity, and the difficulty in using it in a language with no 
syntactic support.)

Whether it is practical to add it to Python, I don't know. I suspect 
that we would have to develop some sort of third-party solution first, 
even if it did not do everything contracts ought to do (or do them less 
efficiently) as a proof of concept. PyContracts is probably a good place 
to start. For those who missed Wes' email:

https://andreacensi.github.io/contracts/

Cobra is another good place to look, as it demonstrates a 
nice syntax that reads like a cross between Python and Eiffel:

http://cobra-language.com/trac/cobra/wiki/Contracts





-- 
Steve
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Pre-conditions and post-conditions

2018-08-21 Thread Marko Ristin-Kaufmann
Hi,

I had a look at the messages related to the PEP in question (PEP 316) in
the archive. As far as I can tell, the main objection is that you can
achieve contracts by implementing it with decorators.

I think that these objections miss what actually Daniel Moisset wrote in
his message: contracts are more than pre- and post-condition checks on a
function. The inheritance of decorators does not imply just inheriting the
pre- and post-conditions, but also relaxing and tightening them
(represented by "require else" and "ensure then" in Eiffel). If this is to
be used effectively in practice with little overhead then we would either
need to introduce new syntax to the language or make the compiler improve
the byte code on the fly.

Is there any chance to introduce these constructs in the language or is it
too small a feature for such a big change?

Since we wanted to have contracts in Golang, we implemented a tool that
synchronizes the documentation of a function with the function code (
https://github.com/Parquery/gocontracts). Maybe this is the easier path to
follow in Python as well?

@Wes Turner: thanks for pointing to pycontracts. I'm aware of the library.
It implements only contracts based on a single property. We found that
limiting and rolled out our own solution that suited us much better:
https://github.com/Parquery/icontract/

I also found informative messages on contract breach to be particularly
important for fast development and error inspection in the production.

Cheers,
Marko


On 21 August 2018 at 04:44, Wes Turner  wrote:

> pycontracts may be worth a look.
>
> https://andreacensi.github.io/contracts/
>
> - @contract decorator, annotations, docstrings
>
> IDK if pycontracts supports runtime parameter validations that involve
> more than one parameter.
>
> Inheritance does appear to be supported,
> as are numpy array dimension constraints.
>
> I can't recall whether the pycontracts expression language precedes MyPy
> compile-time annotations; both with one syntax really would be great.
>
>
> On Monday, August 20, 2018, Daniel Moisset 
> wrote:
>
>> I think that annotations were suggested because you could write an
>> expression there without getting evaluated.
>>
>> I've thought about this problem many times in the past (as a Python dev
>> with a long history working in Eiffel too) For me one of the crucial
>> issue that is hard to translate into the python model is that the
>> assertions (say, a function precondition) are not conceptually part of the
>> function itself, but the interface of the class. The "natural" python ways
>> of attaching these assertions somehow to the function object do not work
>> when you also use inheritance, because when you override a method the new
>> function object clobbers the previous one. I've experimented at some point
>> on how to put them in classes (and doing metaclass or __getattribute__
>> tricks) but nothing convinced me). In general, the way that python puts
>> method call and inheritance semantic in a specific layout of runtime
>> objects (which in general is really clever) seems to be a bit alien to the
>> DbC idea where the asbtraction/interface of the class is conceptually
>> separate and has independent information wrt to the runtime objects.
>>
>>
>> On 16 August 2018 at 18:49, Marko Ristin-Kaufmann > > wrote:
>>
>>> Hi Jonathan and Paul,
>>> Thank you very much for your suggestions! I will try to contact the
>>> author of the PEP.
>>>
>>> Let me clarify a bit a potential misunderstanding. Please mind that
>>> contracts are not tied to individual variables, but to expressions. Think
>>> of it as defining a lambda which takes as input all the arguments of the
>>> function (and a result variable in case of post-conditions) which always
>>> needs to evaluate to True.
>>>
>>> Cheers,
>>> Marko
>>>
>>> Le jeu. 16 août 2018 à 12:24, Paul Moore  a écrit :
>>>
 On Thu, 16 Aug 2018 at 10:41, Jonathan Fine 
 wrote:
 >
 > Hi Marko
 >
 > Thank you for introducing yourself, and clearly stating your question.
 > That helps us all. You asked:
 >
 > > Could somebody update me on the state of the discussion on this
 matter?
 >
 > I think bring the existing PEP up to date would be a good starting
 > point. Its content hasn't been changed since 2003 (except for PEP-wide
 > admin changes. (Recall that Python 3.0 was released in 2008.)
 >
 > https://www.python.org/dev/peps/pep-0316/
 > https://github.com/python/peps/commits/master/pep-0316.txt
 >
 > In fact, revising the PEP might be enough to answer your question.
 > What do you think, Marko?
 >
 > Experts: is there a process for revising old PEPs, such as this one?
 > Or at least a precedent we could follow (or adapt)?

 I'm not aware of a formal process, but I'd have thought the following
 steps would be a reasonable approach:

 1. Review the PEP, and research the discussions that happened at the