Re: [Python-ideas] PEP: Dict addition and subtraction

2019-03-08 Thread James Edwards
On Fri, Mar 8, 2019 at 11:25 AM João Matos  wrote:

> I've just read your PEP 585 draft and have some questions.
> When you say
> "
>
> Like the merge operator and list concatenation, the difference operator
> requires both operands to be dicts, while the augmented version allows any
> iterable of keys.
>
> >>> d - {'spam', 'parrot'}
> Traceback (most recent call last):
>   ...
> TypeError: cannot take the difference of dict and set
>
> >>> d -= {'spam', 'parrot'}
> >>> print(d)
> {'eggs': 2, 'cheese': 'cheddar'}
>
> >>> d -= [('spam', 999)]
> >>> print(d)
> {'spam': 999, 'eggs': 2, 'cheese': 'cheddar', 'aardvark': 'Ethel'}
>
>
> "
>
> The option d -= {'spam', 'parrot'} where parrot does not exist in the d
> dict, will raise an exception (eg. KeyNotFound) or be silent?
>
> The option d -= [('spam', 999)] should remove the pair from the dict,
> correct? But the print that follows still shows it there. It's a mistake or
> am I missing something?
>

My understanding is that:

 - (Q1) Attempting to discard a key not in the target of the augmented
assignment would *not *raise a KeyError (or any Exception for that
matter).  This is analogous to how the - operator works on sets and is
consistent with the pure python implementation towards the bottom of the
PEP.
 - (Q2) This one got me as well while implementing the proposal in cpython,
but there is a difference in what "part" of the RHS the operators "care
about" if the RHS isn't a dict.  The += operator expects 2-tuples and will
treat them as (key, value) pairs.  The -= operator doesn't attempt to
unpack the RHS's elements as += does and expects keys.  So d -= [('spam',
999)] treated the tuple as a *key *and attempted to discard it.

IOW,

d = {
'spam': 999,
('spam', 999): True
}
d -= [('spam', 999)]

Would discard the *key* ('spam', 999) and corresponding value True.

Which highlights a possibly surprising incongruence between the operators:

d = {}
update = [(1,1), (2,2), (3,3)]
d += update
d -= update
assert d == {}  # will raise, as d still has 3 items

Similarly,

d = {}
update = {1:1, 2:2, 3:3}
d += update.items()
d -= update.items()
assert d == {}  # will raise, for the same reason
d -= update.keys()
assert d == {}  # would pass without issue

That being said I (personally) wouldn't consider it a deal-breaker and
still would very much appreciate of the added functionality (regardless of
the choice of operator).

- Jim
___
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] Attribute-Getter Syntax Proposal

2019-03-08 Thread Steven D'Aprano
On Sat, Mar 09, 2019 at 05:19:50PM +1300, Greg Ewing wrote:
> If we were going to add a syntax for abbreviating lambdas, I would
> rather see something more generally useful, e.g.
> 
>x -> x.method()
> 
> as an abbrevation for
> 
>lambda x: x.method()

Cocnut does this!

https://coconut.readthedocs.io/en/latest/DOCS.html#lambdas

It allows any arbitrary expression and parameter list, rather 
than being limited to a single special case:

lambda x, y=None, *args, **kw: spam(x)+y.eggs()-len(args)+kw['foo']

(x, y=None, *args, **kw) -> spam(x)+y.eggs()-len(args)+kw['foo']
# Saves an entire three columns! *wink*


(I believe this is similar to Haskell's syntax.)

Given that we have lambda though, and many people don't like anonymous 
functions, I doubt there's enough advantage to justify adding new 
syntax.

I prefer the look of -> to lambda, but given that we have lambda already 
I wouldn't want to waste that nice looking arrow operator on something we 
already can do. I'd rather see it saved for something more interesting, 
like a hypothetical cascading (fluent) method call syntax, or pattern 
matching.


-- 
Steven
___
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] Attribute-Getter Syntax Proposal

2019-03-08 Thread Greg Ewing

If we were going to add a syntax for abbreviating lambdas, I would
rather see something more generally useful, e.g.

   x -> x.method()

as an abbrevation for

   lambda x: x.method()

--
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/


Re: [Python-ideas] Attribute-Getter Syntax Proposal

2019-03-08 Thread Steven D'Aprano
On Fri, Mar 08, 2019 at 03:43:10PM -0800, Chris Barker - NOAA Federal via 
Python-ideas wrote:
> >
> > Rather than using map in this way, I would recommend a list comprehension:
> 
> Exactly! I really don’t get why folks want to use map() so much when
> the comprehension syntax is often cleaner and easier. It was added for
> a reason :-)

Comprehensions are great for avoiding the need to write verbose lambdas 
before calling map:

map(lambda x: x + 1, numbers)
(x + 1 for x in numbers)

but you typically only save a few characters, and you don't even save 
that when the function already exists:

map(str.upper, strings)
(s.upper() for s in strings)

So horses for courses.

In my opinion, map() looks nicer when you are calling a pre-existing 
named function, and comprehensions look nicer when you have an 
expression involving operators which would otherwise require a lambda.


-- 
Steven
___
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] Preallocated tuples and dicts for function calls

2019-03-08 Thread Steven D'Aprano
On Fri, Mar 08, 2019 at 10:16:02PM +0100, Martin Bammer wrote:
> Hi,
> 
> what about the idea that the interpreter preallocates and 
> preinitializes the tuples and dicts for function calls where possible 
> when loading a module?

That's an implementation detail. CPython may or may not use tuples and 
dicts to call functions, but I don't think that's specified by the 
language. So we're talking about a potential optimization of one 
interpreter, not a language change.

If the idea survives cursory discussion here, the Python-Dev mailing 
list is probably a better place to discuss it further.


> Before calling a function then the interpreter would just need to update
> the items which are dynamic and then call the function.

As Greg points out, that would be unsafe when using threads. Let's say 
you have two threads, A and B, and both call function spam(). A wants to 
call spam(1, 2) and B wants to call spam(3, 4). Because of the 
unpredictable order that threaded code runs, we might have:

A sets the argument tuple to (1, 2)
B sets the argument tuple to (2, 3)
B calls spam()
A calls spam() # Oops!

and mysterious, difficult to reproduce errors occur.

It may be possible to solve this with locks, but that would probably 
slow code down horribly.

[...]
> Without the optimization the interpreter would need to:
> 
> - create new tuple (allocate memory)
> - write constant into first tuple index.
> - create dict (allocate memory)
> - add key+value
> - add key+value
> - call function

Sure, and that happens at runtime, just before the function is called. 
But the same series of allocations would have to occur under your idea 
too, it would just happen when the module loads. And then the pre- 
allocated tuples and dicts would hang around forever, wasting memory. 
Even if it turns out that the function never actually gets called:

for x in sequence:
if condition(x):  # always returns False!
function(...)

the compiler will have pre-allocated the memory to call it.

So I suspect this is going to be very memory hungry. Trading off memory 
for speed might be worthwhile, but it is a trade-off that will make 
certain things worse rather than better.


> If this idea is possible to implement I assume the function calls would
> receive a great speed improvment.

Well, it might decrease the overhead of calling a function, but that's 
usually only a small proportion of the total time to make function 
calls. So it might not help as much as you expect, except in the case 
where you have lots and lots of function calls each of which do only a 
tiny amount of work.

But that has to be balanced against the slowdown that occurs when the 
module loads, when the same memory allocations (but not deallocations) 
would occur. Starting up Python is already pretty slow compared to other 
languages, this would probably make it worse.

Even if it became a nett win for some applications, for others it would 
likely be a nett loss. My guess is that it would probably hurt the cases 
which are already uncomfortably slow, while benefitting the cases that 
don't need much optimization.

But that's just a guess, and not an especially educated guess at that.


-- 
Steven
___
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] PEP: Dict addition and subtraction

2019-03-08 Thread Greg Ewing

Guido van Rossum wrote:
I guess everybody's high school math(s) class was different. I don't 
ever recall seeing + and * for boolean OR/AND; we used ∧ and ∨.


Boolean algebra was only touched on briefly in my high school
years. I can't remember exactly what notation was used, but it
definitely wasn't ∧ and ∨ -- I didn't encounter those until
much later.

However, I've definitely seen texts on boolean alegbra in
relation to logic circuits that write 'A and B' as 'AB',
and 'A or B' as 'A + B'. (And also use an overbar for
negation instead of the mathematical ¬).

Maybe it depends on whether you're a mathematician or an
engineer? The multiplication-addition notation seems a lot
more readable when you have a complicated boolean expression,
so I can imagine it being favoured by pragmatic engineering
type people.

--
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/


Re: [Python-ideas] Preallocated tuples and dicts for function calls

2019-03-08 Thread Greg Ewing

Martin Bammer wrote:

what about the idea that the interpreter preallocates and preinitializes 
the tuples and dicts for function calls where possible when loading a module?


This would not be thread-safe. Locking would be needed around uses
of the preallocated objects, and that might take away some or all
of the gain. It would also introduce unexpected interactions
between threads.

--
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/


Re: [Python-ideas] Attribute-Getter Syntax Proposal

2019-03-08 Thread David Mertz
I'm really old ... I remember thinking how clever attrgetter() was when it
was after to Python 2.4.

On Fri, Mar 8, 2019, 7:51 PM David Mertz  wrote:

> You could use the time machine:
> https://docs.python.org/3/library/operator.html
>
> On Fri, Mar 8, 2019, 11:57 AM Samuel Li  wrote:
>
>> Don't know if this has been suggested before. Instead of writing
>> something like
>>
>> >>> map(lambda x: x.upper(), ['a', 'b', 'c'])
>>
>> I suggest this syntax:
>> >>> map(.upper(), ['a', 'b', 'c'])
>>
>> This would also work for attributes:
>> >>> map(.real, [1j, 2, 3+4j])
>>
>> Internally, this would require translating
>>
>> .attribute -> lambda x: x.attribute
>>
>> and
>>
>> .method(*args, **kwargs) -> lambda x: x.method(*args, **kwargs)
>>
>> This translation should only take place where a "normal" attribute lookup
>> makes no sense (throws a SyntaxError); i.e. foo.bar works as before,
>> foo(.bar) would previously throw a SyntaxError, so the new syntax applies
>> and the .bar is interpreted as an attrgetter.
>>
>> This is of course only a cosmetic improvement over operator.attrgetter
>> and operator.methodcaller, but I think it's nice enough to warrant
>> consideration.
>>
>> If you like this idea or think it's utter garbage, feel free to discuss.
>> ___
>> 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] Attribute-Getter Syntax Proposal

2019-03-08 Thread David Mertz
You could use the time machine:
https://docs.python.org/3/library/operator.html

On Fri, Mar 8, 2019, 11:57 AM Samuel Li  wrote:

> Don't know if this has been suggested before. Instead of writing something
> like
>
> >>> map(lambda x: x.upper(), ['a', 'b', 'c'])
>
> I suggest this syntax:
> >>> map(.upper(), ['a', 'b', 'c'])
>
> This would also work for attributes:
> >>> map(.real, [1j, 2, 3+4j])
>
> Internally, this would require translating
>
> .attribute -> lambda x: x.attribute
>
> and
>
> .method(*args, **kwargs) -> lambda x: x.method(*args, **kwargs)
>
> This translation should only take place where a "normal" attribute lookup
> makes no sense (throws a SyntaxError); i.e. foo.bar works as before,
> foo(.bar) would previously throw a SyntaxError, so the new syntax applies
> and the .bar is interpreted as an attrgetter.
>
> This is of course only a cosmetic improvement over operator.attrgetter and
> operator.methodcaller, but I think it's nice enough to warrant
> consideration.
>
> If you like this idea or think it's utter garbage, feel free to discuss.
> ___
> 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] Left arrow and right arrow operators

2019-03-08 Thread Greg Ewing

francismb wrote:

It is may be how now it is, but means that it
needs to be always like this?


Yes, as long as you care about not breaking existing code. While
you may be in the habit of always leaving a space between '<'
and '-', others may have different styles. Do you really want
to tell them that all their code is now wrong?

--
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/


Re: [Python-ideas] PEP: Dict addition and subtraction

2019-03-08 Thread Guido van Rossum
On Fri, Mar 8, 2019 at 3:33 PM Greg Ewing 
wrote:

> Guido van Rossum wrote:
> > I guess this explains the behavior of removing results <= 0; it makes
> > sense as multiset subtraction, since in a multiset a negative count
> > makes little sense. (Though the name Counter certainly doesn't seem to
> > imply multiset.)
>
> It doesn't even behave consistently as a multiset, since c[k] -= n
> is happy to let the value go negative.
>
> > For sets,
> > union and intersection are distributive over each other.
>
> > Note that this is *not* the case for + and * when used with
> > (mathematical) numbers... So in a sense, SETL (which uses + and *
>  > for union and intersection got the operators wrong.
>
> But in another sense, it didn't. In Boolean algebra, "and" and "or"
> (which also distribute over each other) are often written using the
> same notations as multiplication and addition. There's no rule in
> mathematics saying that these notations must be distributive in one
> direction but not the other.
>

I guess everybody's high school math(s) class was different. I don't ever
recall seeing + and * for boolean OR/AND; we used ∧ and ∨.

I learned | and & for set operations only after I learned programming; I
think it was in PL/1. But of course it stuck because of C bitwise operators
(which are also boolean OR/AND and set operations).

This table suggests there's a lot of variety in how these operators are
spelled:
https://en.wikipedia.org/wiki/List_of_logic_symbols

-- 
--Guido van Rossum (python.org/~guido)
___
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] Attribute-Getter Syntax Proposal

2019-03-08 Thread Greg Ewing

Samuel Li wrote:

.attribute -> lambda x: x.attribute

.method(*args, **kwargs) -> lambda x: x.method(*args, **kwargs)


Leading dots can be hard to spot when reading code.

Also, I'm not convinced that use cases for this are frequent enough
to warrant new syntax.

Something akin to this can already be done in simple cases:

   map(string.upper, some_list)

Anything more complicated, such as passing arguments, is probably
better expressed with a comprehension.

--
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/


Re: [Python-ideas] Attribute-Getter Syntax Proposal

2019-03-08 Thread Chris Barker - NOAA Federal via Python-ideas
>
> Rather than using map in this way, I would recommend a list comprehension:

Exactly! I really don’t get why folks want to use map() so much when
the comprehension syntax is often cleaner and easier. It was added for
a reason :-)

-CHB
___
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] PEP: Dict addition and subtraction

2019-03-08 Thread Greg Ewing

Guido van Rossum wrote:
I guess this explains the behavior of removing results <= 0; it makes 
sense as multiset subtraction, since in a multiset a negative count 
makes little sense. (Though the name Counter certainly doesn't seem to 
imply multiset.)


It doesn't even behave consistently as a multiset, since c[k] -= n
is happy to let the value go negative.

For sets, 
union and intersection are distributive over each other.


Note that this is *not* the case for + and * when used with 
(mathematical) numbers... So in a sense, SETL (which uses + and *

> for union and intersection got the operators wrong.

But in another sense, it didn't. In Boolean algebra, "and" and "or"
(which also distribute over each other) are often written using the
same notations as multiplication and addition. There's no rule in
mathematics saying that these notations must be distributive in one
direction but not the other.

--
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/


Re: [Python-ideas] Attribute-Getter Syntax Proposal

2019-03-08 Thread Benedikt Werner

I just realized it doesn't work properly if the method takes some arguments,
so you would actually have to use two different magic objects or 
something like that,

but I guess the point is clear.

Am 08.03.2019 um 23:08 schrieb Benedikt Werner:
This was actually quite interesting to code, thanks for the idea 
Jonathan!


You can even support "magic.upper()" and "magic.real" at the same time 
as well as "magic[0]":


class MagicClass:
    NO_ARG = object()

    @staticmethod
    def __getattribute__(attr):
    def method(x=MagicClass.NO_ARG):
    if x is MagicClass.NO_ARG:
    return lambda x: getattr(x, attr)()
    return getattr(x, attr)
    return method

    @staticmethod
    def __getitem__(attr):
    return lambda x: x[attr]

magic = MagicClass()

print(list(map(magic.upper(), ["abc", "def"])))  # ['ABC', 'DEF']
print(list(map(magic.real, [1j, 2, 3+4j])))  # [0.0, 2, 3.0]
print(list(map(magic[0], ["abc", "def"])))   # ['a', 'd']

You could also use None instead of that NO_ARG thingy, because you 
most likely won't want to get any attributes of None objects, but that 
wouldn't produce proper errors incase you do anyways.


With metaclasses you propably could also make it work directly on the 
class without the need of a magic instance.


Benedikt

Am 08.03.2019 um 19:07 schrieb Jonathan Fine:

Hi Samuel

Interesting idea, and certainly addresses a real problem, if you find
yourself creating lots of lambda expressions. But in my first opinion,
not so useful that it merits adding to the syntax of Python.

(Even if I never use it, it puts an extra burden on me when scanning
Python code. Something that used to look like a syntax error is now
valid. That's more work for me.)

However, you can already achieve something similar, and perhaps more
expressive. It is possible to define an object 'magic' such that
    fn = magic.upper
    fn = lambda x: x.upper()
are effectively equivalent.

And this can be done now. No need for a PEP and a new version of
Python. And available for those who have to use some fixed already
existing Python versions.

I hope you'd be interesting in coding this up yourself. I'd have a
limited amount of time to help you, but it would put you on a good
learning curve, for fundamentals of the Python object model.


___
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] Attribute-Getter Syntax Proposal

2019-03-08 Thread Chris Angelico
On Sat, Mar 9, 2019 at 9:09 AM Benedikt Werner
<1benediktwer...@gmail.com> wrote:
>
> This was actually quite interesting to code, thanks for the idea Jonathan!
>
> You can even support "magic.upper()" and "magic.real" at the same time
> as well as "magic[0]":
>
> class MagicClass:
>  NO_ARG = object()
>
>  @staticmethod
>  def __getattribute__(attr):
>  def method(x=MagicClass.NO_ARG):
>  if x is MagicClass.NO_ARG:
>  return lambda x: getattr(x, attr)()
>  return getattr(x, attr)
>  return method
>
>  @staticmethod
>  def __getitem__(attr):
>  return lambda x: x[attr]
>
> magic = MagicClass()
>
> print(list(map(magic.upper(), ["abc", "def"])))  # ['ABC', 'DEF']
> print(list(map(magic.real, [1j, 2, 3+4j])))  # [0.0, 2, 3.0]
> print(list(map(magic[0], ["abc", "def"])))   # ['a', 'd']
>
> You could also use None instead of that NO_ARG thingy, because you most
> likely won't want to get any attributes of None objects, but that
> wouldn't produce proper errors incase you do anyways.
>
> With metaclasses you propably could also make it work directly on the
> class without the need of a magic instance.

Rather than using map in this way, I would recommend a list comprehension:

print([x.upper() for x in ["abc", "def"]])
print([x.real for x in [1j, 2, 3+4j]])
print([x[0] for x in ["abc", "def"]])

No magic 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] Attribute-Getter Syntax Proposal

2019-03-08 Thread Benedikt Werner

This was actually quite interesting to code, thanks for the idea Jonathan!

You can even support "magic.upper()" and "magic.real" at the same time 
as well as "magic[0]":


class MagicClass:
    NO_ARG = object()

    @staticmethod
    def __getattribute__(attr):
    def method(x=MagicClass.NO_ARG):
    if x is MagicClass.NO_ARG:
    return lambda x: getattr(x, attr)()
    return getattr(x, attr)
    return method

    @staticmethod
    def __getitem__(attr):
    return lambda x: x[attr]

magic = MagicClass()

print(list(map(magic.upper(), ["abc", "def"])))  # ['ABC', 'DEF']
print(list(map(magic.real, [1j, 2, 3+4j])))  # [0.0, 2, 3.0]
print(list(map(magic[0], ["abc", "def"])))   # ['a', 'd']

You could also use None instead of that NO_ARG thingy, because you most 
likely won't want to get any attributes of None objects, but that 
wouldn't produce proper errors incase you do anyways.


With metaclasses you propably could also make it work directly on the 
class without the need of a magic instance.


Benedikt

Am 08.03.2019 um 19:07 schrieb Jonathan Fine:

Hi Samuel

Interesting idea, and certainly addresses a real problem, if you find
yourself creating lots of lambda expressions. But in my first opinion,
not so useful that it merits adding to the syntax of Python.

(Even if I never use it, it puts an extra burden on me when scanning
Python code. Something that used to look like a syntax error is now
valid. That's more work for me.)

However, you can already achieve something similar, and perhaps more
expressive. It is possible to define an object 'magic' such that
fn = magic.upper
fn = lambda x: x.upper()
are effectively equivalent.

And this can be done now. No need for a PEP and a new version of
Python. And available for those who have to use some fixed already
existing Python versions.

I hope you'd be interesting in coding this up yourself. I'd have a
limited amount of time to help you, but it would put you on a good
learning curve, for fundamentals of the Python object model.


___
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] Preallocated tuples and dicts for function calls

2019-03-08 Thread Martin Bammer
Hi,

what about the idea that the interpreter preallocates and preinitializes
the

tuples and dicts for function calls where possible when loading a module?


Before calling a function then the interpreter would just need to update
the

items which are dynamic and then call the function.


Some examples:


msgpack.unpackb(b'\x93\x01\x02\x03', use_list=False, raw=False)


The above function call needs a tuple with 1 entry and a dict with 2
entries.

All entries are constant. So in this case the interpreter can immediately

execute the function call.


Without the optimization the interpreter would need to:

- create new tuple (allocate memory)

- write constant into first tuple index.

- create dict (allocate memory)

- add key+value

- add key+value

- call function



Another example:


foo(bar, 3, 5, arg1=bar1, arg2=True)


The above needs a tuple with 3 entries. 2 of them are constant. And a dict

with 2 entries. 1 of them is constant.


With the optimization:

- write bar into first tuple index.

- replace first key+value pair in the dict.

- call function


Without the optimization:

- create new tuple (allocate memory)

- write bar into first tuple index.

- write constant into second tuple index.

- write constant into third tuple index.

- create dict (allocate memory)

- add key+value

- add key+value

- call function



If this idea is possible to implement I assume the function calls would

receive a great speed improvment.


Best regards,

Martin
___
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] Left arrow and right arrow operators

2019-03-08 Thread Chris Angelico
On Sat, Mar 9, 2019 at 7:05 AM francismb  wrote:
>
> Hi Oleg,
>
> On 3/3/19 4:06 PM, Oleg Broytman wrote:
> >You cannot create operator ``<-`` because it's currently valid
> > syntax:
> >
> > 3 <- 2
> >
> > is equivalent to
> >
> > 3 < -2
>
> Yes, its a good point, but for me it's not the same '<-' and '< -' due
> (n)blanks in between. It is may be how now it is, but means that it
> needs to be always like this? Isn't Python not already
> blank(s)/indentation aware? or it's just a grammar NO GO?
>

Python permits "3<-2", so this is indeed a no-go. You can easily test
this at the interactive 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] Left arrow and right arrow operators

2019-03-08 Thread francismb
Hi Oleg,

On 3/3/19 4:06 PM, Oleg Broytman wrote:
>You cannot create operator ``<-`` because it's currently valid
> syntax:
>
> 3 <- 2
>
> is equivalent to
>
> 3 < -2

Yes, its a good point, but for me it's not the same '<-' and '< -' due
(n)blanks in between. It is may be how now it is, but means that it
needs to be always like this? Isn't Python not already
blank(s)/indentation aware? or it's just a grammar NO GO?

Thanks in advance!
--francis
___
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] Left arrow and right arrow operators

2019-03-08 Thread francismb
Hi fhsxfhsx,

On 3/4/19 5:56 AM, fhsxfhsx wrote:
> Could you explain why do you prefer this operator than `+`?
Well yes, because of the asymmetric operation done underneath (merging
dicts is not symmetric). The asymmetry is explicit in the symbol. Not
implicit from the documentation you need to know/read for + (in the case
proposed for dictionaries).

Regards,
--francis


___
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] Left arrow and right arrow operators

2019-03-08 Thread francismb
Hi Calvin,

On 3/4/19 2:09 PM, Calvin Spealman wrote:
> I don't like the idea of arrows in both directions when you can just swap
> the operands instead
Well you saw just to examples of contexts (dict and bool). Could you
imagine a context where swapping cannot be done and thus there is a need
for left- and right arrow?

Thanks in advance!
--francis

___
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] Left arrow and right arrow operators

2019-03-08 Thread francismb
Hi Todd,

On 3/4/19 2:18 PM, Todd wrote:
> What is the operator supposed to do?
this should depend on what you want to do, the type, the context.

How to you would want to use it ? do you see a context where the symbols
make meaning to you?

Thanks in advance!
--francis
___
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] PEP: Dict addition and subtraction

2019-03-08 Thread MRAB

On 2019-03-08 16:55, Guido van Rossum wrote:
[snip]
If we were to use "|" and "&" for dict "union" and "intersection", the 
mutual distributive properties will hold.


Since "|" (especially "|=") *is* suitable for "update", I think we
should reserve "+" for some future commutative extension.


One argument is that sets have an update() method aliased to "|=", so 
this makes it more reasonable to do the same for dicts, which also have 
a. update() method, with similar behavior (not surprising, since sets 
were modeled after dicts).



[snip]
One way to think of it is that a dict is like a set, except that each of 
its members has an additional associated value.

___
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] Attribute-Getter Syntax Proposal

2019-03-08 Thread Brett Cannon
On Fri, Mar 8, 2019 at 8:57 AM Samuel Li  wrote:

> Don't know if this has been suggested before. Instead of writing something
> like
>
> >>> map(lambda x: x.upper(), ['a', 'b', 'c'])
>
> I suggest this syntax:
> >>> map(.upper(), ['a', 'b', 'c'])
>

Do note you get the same results with `map(str.upper, ['a', 'b', 'c'])`.


>
> This would also work for attributes:
> >>> map(.real, [1j, 2, 3+4j])
>
> Internally, this would require translating
>
> .attribute -> lambda x: x.attribute
>
> and
>
> .method(*args, **kwargs) -> lambda x: x.method(*args, **kwargs)
>
> This translation should only take place where a "normal" attribute lookup
> makes no sense (throws a SyntaxError); i.e. foo.bar works as before,
> foo(.bar) would previously throw a SyntaxError, so the new syntax applies
> and the .bar is interpreted as an attrgetter.
>
> This is of course only a cosmetic improvement over operator.attrgetter and
> operator.methodcaller, but I think it's nice enough to warrant
> consideration.
>
> If you like this idea or think it's utter garbage, feel free to discuss.
>

Sorry, I'm personally not a fan as it looks like you have a typo in your
code, e.g. you left of 'x' or something before the dot.
___
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] Attribute-Getter Syntax Proposal

2019-03-08 Thread Jonathan Fine
Hi Samuel

Interesting idea, and certainly addresses a real problem, if you find
yourself creating lots of lambda expressions. But in my first opinion,
not so useful that it merits adding to the syntax of Python.

(Even if I never use it, it puts an extra burden on me when scanning
Python code. Something that used to look like a syntax error is now
valid. That's more work for me.)

However, you can already achieve something similar, and perhaps more
expressive. It is possible to define an object 'magic' such that
   fn = magic.upper
   fn = lambda x: x.upper()
are effectively equivalent.

And this can be done now. No need for a PEP and a new version of
Python. And available for those who have to use some fixed already
existing Python versions.

I hope you'd be interesting in coding this up yourself. I'd have a
limited amount of time to help you, but it would put you on a good
learning curve, for fundamentals of the Python object model.

-- 
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] Attribute-Getter Syntax Proposal

2019-03-08 Thread Samuel Li
Don't know if this has been suggested before. Instead of writing something
like

>>> map(lambda x: x.upper(), ['a', 'b', 'c'])

I suggest this syntax:
>>> map(.upper(), ['a', 'b', 'c'])

This would also work for attributes:
>>> map(.real, [1j, 2, 3+4j])

Internally, this would require translating

.attribute -> lambda x: x.attribute

and

.method(*args, **kwargs) -> lambda x: x.method(*args, **kwargs)

This translation should only take place where a "normal" attribute lookup
makes no sense (throws a SyntaxError); i.e. foo.bar works as before,
foo(.bar) would previously throw a SyntaxError, so the new syntax applies
and the .bar is interpreted as an attrgetter.

This is of course only a cosmetic improvement over operator.attrgetter and
operator.methodcaller, but I think it's nice enough to warrant
consideration.

If you like this idea or think it's utter garbage, feel free to discuss.
___
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] PEP: Dict addition and subtraction

2019-03-08 Thread Guido van Rossum
On Thu, Mar 7, 2019 at 9:12 PM Stephen J. Turnbull <
turnbull.stephen...@u.tsukuba.ac.jp> wrote:

> Ka-Ping Yee writes:
>  > On Wed, Mar 6, 2019 at 4:01 PM Chris Angelico  wrote:
>
>  > > But adding dictionaries is fundamentally *useful*. It is expressive.
>  >
>  > It is useful.  It's just that + is the wrong name.
>
> First, let me say that I prefer ?!'s position here, so my bias is made
> apparent.  I'm also aware that I have biases so I'm sympathetic to
> those who take a different position.
>

TBH, I am warming up to "|" as well.


> Rather than say it's "wrong", let me instead point out that I think
> it's pragmatically troublesome to use "+".  I can think of at least
> four interpretations of "d1 + d2"
>
> 1.  update
> 2.  multiset (~= Collections.Counter addition)
>

I guess this explains the behavior of removing results <= 0; it makes sense
as multiset subtraction, since in a multiset a negative count makes little
sense. (Though the name Counter certainly doesn't seem to imply multiset.)


> 3.  addition of functions into the same vector space (actually, a
> semigroup will do ;-), and this is the implementation of
> Collections.Counter
> 4.  "fiberwise" set addition (ie, of functions into relations)
>
> and I'm very jet-lagged so I may be missing some.
>
> There's also the fact that the operations denoted by "|" and "||" are
> often implemented as "short-circuiting", and therefore not
> commutative, while "+" usually is (and that's reinforced for
> mathematicians who are trained to think of "+" as the operator for
> Abelian groups, while "*" is a (possibly) non-commutative operator.  I
> know commutativity of "+" has been mentioned before, but the
> non-commutativity of "|" -- and so unsuitability for many kinds of
> dict combination -- hasn't been emphasized before IIRC.
>

I've never heard of single "|" being short-circuiting. ("||" of course is
infamous for being that in C and most languages derived from it.)

And "+" is of course used for many non-commutative operations in Python
(e.g. adding two lists/strings/tuples together). It is only *associative*,
a weaker requirement that just says (A + B) + C == A + (B + C). (This is
why we write A + B + C, since the grouping doesn't matter for the result.)

Anyway, while we're discussing mathematical properties, and since SETL was
briefly mentioned, I found an interesting thing in math. For sets, union
and intersection are distributive over each other. I can't type the
operators we learned in high school, so I'll use Python's set operations.
We find that A | (B & C) == (A | B) & (A | C). We also find that A & (B |
C) == (A & B) | (A & C).

Note that this is *not* the case for + and * when used with (mathematical)
numbers: * distributes over +: a * (b + c) == (a * b) + (a * c), but + does
not distribute over *: a + (b * c) != (a + b) * (a + c). So in a sense,
SETL (which uses + and * for union and intersection) got the operators
wrong.

Note that in Python, + and * for sequences are not distributive this way,
since (A + B) * n is not the same as (A * n) + (B * n). OTOH A * (n + m) ==
A * n + A * m. (Assuming A and B are sequences of the same type, and n and
m are positive integers.)

If we were to use "|" and "&" for dict "union" and "intersection", the
mutual distributive properties will hold.


> Since "|" (especially "|=") *is* suitable for "update", I think we
> should reserve "+" for some future commutative extension.
>

One argument is that sets have an update() method aliased to "|=", so this
makes it more reasonable to do the same for dicts, which also have a.
update() method, with similar behavior (not surprising, since sets were
modeled after dicts).


> In the spirit of full disclosure:
> Of these, 2 is already implemented and widely used, so we don't need
> to use dict.__add__ for that.  I've never seen 4 in the mathematical
> literature (union of relations is not the same thing).  3, however, is
> very common both for mappings with small domain and sparse
> representation of mappings with a default value (possibly computed
> then cached), and "|" is not suitable for expressing that sort of
> addition (I'm willing to say it's "wrong" :-).
>

-- 
--Guido van Rossum (python.org/~guido)
___
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] PEP: Dict addition and subtraction

2019-03-08 Thread João Matos

  
  
Hello,

I've just read your PEP 585 draft and have some questions.
When you say
"
Like the merge operator and list concatenation, the difference
  operator requires both operands to be dicts, while the augmented
  version allows any iterable of keys.

  >>> d - {'spam', 'parrot'}
Traceback (most recent call last):
  ...
TypeError: cannot take the difference of dict and set

  >>> d -= {'spam', 'parrot'}
>>> print(d)
{'eggs': 2, 'cheese': 'cheddar'}

  >>> d -= [('spam', 999)]
>>> print(d)
{'spam': 999, 'eggs': 2, 'cheese': 'cheddar', 'aardvark': 'Ethel'}
 


"

The option d -= {'spam', 'parrot'} where parrot does not exist in
the d dict, will raise an exception (eg. KeyNotFound) or be silent?

The option d -= [('spam', 999)] should remove the pair from the
dict, correct? But the print that follows still shows it there. It's
a mistake or am I missing something?


Best regards,

João Matos


  




smime.p7s
Description: S/MIME Cryptographic Signature
___
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] Dict joining using + and +=

2019-03-08 Thread Davide Rizzo
> Counter also uses +/__add__ for a similar behavior.
>
> >>> c = Counter(a=3, b=1)
> >>> d = Counter(a=1, b=2)
> >>> c + d # add two counters together:  c[x] + d[x]
> Counter({'a': 4, 'b': 3})
>
> At first I worried that changing base dict would cause confusion for the 
> subclass, but Counter seems to share the idea that update and + are synonyms.

Counter is a moot analogy. Counter's + and - operators follow the
rules of numbers addition and subtraction:

>>> c = Counter({"a": 1})
>>> c + Counter({"a": 5})
Counter({'a': 6})
>>> c + Counter({"a": 5}) - Counter({"a": 4})
Counter({'a': 2})

Which also means that in most cases (c1 + c2) - c2 == c1 which is not
something you would expect with the suggested "dictionary addition"
operation. As a side note, this is not true in general for Counters
because of how subtraction handles 0. E.g.

>>> c0 = Counter({"a": 0})
>>> c1 = Counter({"a": 1})
>>> (c0 + c1) - c1
Counter()
>>> (c0 + c1) - c1 == c0
False

---

The current intuition of how + and - work don't apply literally to
this suggestion:

1) numeric types are their own story
2) most built-in sequences imply concatenation for + and have no subtraction
3) numpy-like arrays behave closer to numbers
4) Counters mimic numbers in some ways and while addition reminds of
concatenation (but order is not relevant) they also have subtraction
5) sets have difference which is probably the closest you expect from
dict subtraction, but no + operator

---

I understand the arguments against a | operator for dicts but I don't
entirely agree with them. dict is obviously a different type of object
than all the others I've mentioned, even mathematically, and there is
no clear precedent. If sets happened to maintain insertion order, like
dicts after 3.6/3.7, I would expect the union operator to also
preserve the order. Before 3.6 we probably would have seen dicts as
closer to sets from that point of view, and this suggested addition as
closer to set union.

The question of symmetry ({"a": 1} + {"a": 2}) is an important one and
I would consider not enforcing one resolution in PEP 584, and instead
leave this undefined (i.e. in the resulting dict, the value could be
either 1 or 2, or just completely undefined to also be compatible with
Counter-like semantics in the same PEP). This is something to consider
carefully if the plan is to make the new operators part of Mapping.
It's not obvious that all mappings should implement this the same way,
and a survey of what is being done by other implementation of Mappings
would be useful. On the other hand leaving it undefined might make it
harder to standardize it later, once other implementations have
defined their own behavior.

This question is probably on its own a valid argument against the
proposal. When it comes to dicts (and not Mappings in general) {**d1,
**d2} or d.update() already have clearly-defined semantics. The new
proposal for a merge() operation might be more useful. The added value
would be the ability to add two mappings regardless of concrete type.
But it's with Mappings in general that this proposal is the most
problematic.

On the other hand the subtraction operator is probably less
controversial and immediately useful (the idiom to remove keys from a
dictionary is not obvious).
___
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] Suggestions: dict.flow_update and dict.__add__

2019-03-08 Thread Jonathan Fine
I've just learnt something new. Look at

>>> from operator import iadd
>>> lst = [1, 2, 3]
>>> iadd(lst, 'hi')
[1, 2, 3, 'h', 'i']
>>> lst
[1, 2, 3, 'h', 'i']

This shows that the proposals dict.flow_update and dict.__iadd__ are
basically the same. (I think this is quite important for understanding
the attraction of fluent programming. We ALREADY like and use it, in
the form of augmented assignment of mutables.)

This also shows that
   combined = defaults.copy()
   combined.update(options)
could, if the proposal is accepted, be written as
   defaults.copy().__iadd__(options)

I got the idea from the withdrawn PEP (thank you, Nick Coghlan, for writing it):
PEP 577 -- Augmented Assignment Expressions
https://www.python.org/dev/peps/pep-0577/

-- 
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/