[Python-Dev] Re: Delayed evaluation of f-strings?

2021-06-25 Thread Eric Nieuwland

> On 24 Jun 2021, at 10:28, micro codery  wrote:
> 
> As pointed out already, f-strings and format are subtly different (not
> counting that one can eval and the other cannot). Besides quoting, the
> f-sting mini language has diverged from format's
 spam="Spam"
 f"{spam=}"
> "spam='Spam'"
 "{spam=}".format(spam=spam)
> Traceback (most recent call last):
>  File "", line 1, in 
> KeyError: 'spam='
> 
> I created a package some time ago to do exactly this
> https://pypi.org/project/f-yeah/

Lovely! Thanks.

—eric
___
Python-Dev mailing list -- python-dev@python.org
To unsubscribe send an email to python-dev-le...@python.org
https://mail.python.org/mailman3/lists/python-dev.python.org/
Message archived at 
https://mail.python.org/archives/list/python-dev@python.org/message/RIWZ6ABBMQXB32QVUCJU43QZM3HNZ74R/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: Delayed evaluation of f-strings?

2021-06-24 Thread Eric Nieuwland
Except I like the mini-language of f-strings much better than format()’s.
And there is a performance difference between f-strings and format().


> On 24 Jun 2021, at 19:03, Luciano Ramalho  wrote:
> 
> I don't think that would be a good idea since we already have
> .format() which covers that use case and is more flexible than
> f-strings (it supports positional arguments, as well as *args and
> **kwargs).
> 
> I think keeping f-strings simple is a better idea.
> 
> Best,
> 
> Luciano
> 
> On Thu, Jun 24, 2021 at 1:30 PM Eric Nieuwland  
> wrote:
>> 
>> In a recent discussion with a colleague we wondered if it would be possible 
>> to postpone the evaluation of an f-string so we could use it like a regular 
>> string and .format() or ‘%’.
>> 
>> I found 
>> https://stackoverflow.com/questions/42497625/how-to-postpone-defer-the-evaluation-of-f-strings
>>  and tweaked it a bit to:
>> 
>> import inspect
>> 
>> class DelayedFString(str):
>>def __str__(self):
>>vars = inspect.currentframe().f_back.f_globals.copy()
>>vars.update(inspect.currentframe().f_back.f_locals)
>>return self.format(**vars)
>> 
>> delayed_fstring = DelayedFString("The current name is {name}")
>> 
>> # use it inside a function to demonstrate it gets the scoping right
>> def new_scope():
>>names = ["foo", "bar"]
>>for name in names:
>>print(delayed_fstring)
>> 
>> new_scope()
>> 
>> 
>> While this does what it should it is very slow.
>> So I wondered whether it would be an idea to introduce d-strings (delayed 
>> f-strings) and make f-strings syntactic sugar for
>> 
>> f"The current name is {name}" = str(d"The current name is {name}")
>> 
>> 
>> And perhaps access to the variables and conversions specified in the 
>> d-string.
>> 
>> ___
>> Python-Dev mailing list -- python-dev@python.org
>> To unsubscribe send an email to python-dev-le...@python.org
>> https://mail.python.org/mailman3/lists/python-dev.python.org/
>> Message archived at 
>> https://mail.python.org/archives/list/python-dev@python.org/message/GT5DNA7RKRLFWE3V42OTWB7X5ER7KNSL/
>> Code of Conduct: http://python.org/psf/codeofconduct/
> 
> 
> 
> -- 
> Luciano Ramalho
> |  Author of Fluent Python (O'Reilly, 2015)
> | http://shop.oreilly.com/product/0636920032519.do
> |  Technical Principal at ThoughtWorks
> |  Twitter: @ramalhoorg

___
Python-Dev mailing list -- python-dev@python.org
To unsubscribe send an email to python-dev-le...@python.org
https://mail.python.org/mailman3/lists/python-dev.python.org/
Message archived at 
https://mail.python.org/archives/list/python-dev@python.org/message/YJQDXGTFX7G2P6OLYT3QF3IFN7Z65FSG/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: Delayed evaluation of f-strings?

2021-06-24 Thread Eric Nieuwland
I didn’t make myself clear, sorry.

The code example was just to give an initial what I was suggesting.
The errors you show demonstrate the example is incomplete.
I’d like them to work.

> On 24 Jun 2021, at 18:37, Martin (gzlist)  wrote:
> 
> On Thu, 24 Jun 2021 at 17:25, Eric Nieuwland  wrote:
>> 
>> class DelayedFString(str):
>>def __str__(self):
>>vars = inspect.currentframe().f_back.f_globals.copy()
>>vars.update(inspect.currentframe().f_back.f_locals)
>>return self.format(**vars)
> 
> This isn't quite right as the semantics between f-strings and
> str.format() are not actually the same (though this isn't well
> documented):
> 
>>>> f'{1 + 2}'
>'3'
>>>> str(DelayedFString('{1 + 2}'))
>Traceback (most recent call last):
>  File "", line 1, in 
>  File "", line 5, in __str__
>KeyError: '1 + 2'
> 
>>>> d = dict(a=1)
>>>> f'{d["a"]}'
>'1'
>>>> str(DelayedFString('{d["a"]}'))
>Traceback (most recent call last):
>  File "", line 1, in 
>  File "", line 5, in __str__
>KeyError: '"a"'
> 
> Basically, f-strings rely on eval-like semantics.
> 
> Martin

___
Python-Dev mailing list -- python-dev@python.org
To unsubscribe send an email to python-dev-le...@python.org
https://mail.python.org/mailman3/lists/python-dev.python.org/
Message archived at 
https://mail.python.org/archives/list/python-dev@python.org/message/L5U7ES6PS5LW532PAP62CD4PU55WEBAI/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Delayed evaluation of f-strings?

2021-06-24 Thread Eric Nieuwland
In a recent discussion with a colleague we wondered if it would be possible to 
postpone the evaluation of an f-string so we could use it like a regular string 
and .format() or ‘%’.

I found 
https://stackoverflow.com/questions/42497625/how-to-postpone-defer-the-evaluation-of-f-strings
 and tweaked it a bit to:

import inspect

class DelayedFString(str):
def __str__(self):
vars = inspect.currentframe().f_back.f_globals.copy()
vars.update(inspect.currentframe().f_back.f_locals)
return self.format(**vars)

delayed_fstring = DelayedFString("The current name is {name}")

# use it inside a function to demonstrate it gets the scoping right
def new_scope():
names = ["foo", "bar"]
for name in names:
print(delayed_fstring)

new_scope()

While this does what it should it is very slow.
So I wondered whether it would be an idea to introduce d-strings (delayed 
f-strings) and make f-strings syntactic sugar for

f"The current name is {name}" = str(d"The current name is {name}")

And perhaps access to the variables and conversions specified in the d-string.

___
Python-Dev mailing list -- python-dev@python.org
To unsubscribe send an email to python-dev-le...@python.org
https://mail.python.org/mailman3/lists/python-dev.python.org/
Message archived at 
https://mail.python.org/archives/list/python-dev@python.org/message/GT5DNA7RKRLFWE3V42OTWB7X5ER7KNSL/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: The repr of a sentinel

2021-05-25 Thread Eric Nieuwland

To add to the suggestions already given in this thread I dug into code I wrote 
some time ago.
Offered as an inspiration.

=== missing.py ===

from typing import Any

def MISSING(klass: Any) -> Any:
"""
create a sentinel to indicate a missing instance of a class
:param klass: the class of which an instance is missing
:return: missing class object
"""
g = globals()
missing_klass_name = 
f"_MISSING_{klass.__module__}_{klass.__name__}_MISSING_"
if missing_klass_name not in g:
g[missing_klass_name] = type(
missing_klass_name,
(klass,),
{
"__repr__": lambda x: f"MISSING({klass.__name__})",
}
)
return g[missing_klass_name]()

===

and as a demo:

=== demo_missing.py ===

import pickle

from missing import MISSING

x = MISSING(str)
y = "bar"
print(f"{x!r} == {y!r}: {x == y}")
print(f"{x!r} is {y!r}: {x is y}")
# MISSING(str) == 'bar': False
# MISSING(str) is 'bar': False

with open("object.pickled", "wb") as f:
pickle.dump(x, f)
with open("object.pickled", "rb") as f:
y = pickle.load(f)
print(f"{x!r} == {y!r}: {x == y}")
print(f"{x!r} is {y!r}: {x is y}")
# MISSING(str) == MISSING(str): True
# MISSING(str) is MISSING(str): False

def foo(a: int = MISSING(int), b: int = MISSING(int)):
print(f"{a=} {isinstance(a, int)}")
print(f"{b=} {isinstance(b, int)}")
print(f"{a!r} == {b!r}: {a == b}")
print(f"{a!r} is {b!r}: {a is b}")

foo()
# a=MISSING(int) True
# b=MISSING(int) True
# MISSING(int) == MISSING(int): True
# MISSING(int) is MISSING(int): False

foo(1)
# a=1 True
# b=MISSING(int) True
# 1 == MISSING(int): False
# 1 is MISSING(int): False

class Test:
...

t = MISSING(Test)
print(f"{t=}")
# t=MISSING(Test)

===___
Python-Dev mailing list -- python-dev@python.org
To unsubscribe send an email to python-dev-le...@python.org
https://mail.python.org/mailman3/lists/python-dev.python.org/
Message archived at 
https://mail.python.org/archives/list/python-dev@python.org/message/NABTH4G5IZZYCFSH2RBQNLQL3BKEUFKQ/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: The repr of a sentinel

2021-05-15 Thread Eric Nieuwland
To add to the suggestions already given in this thread I dug into code I wrote 
some time ago.
Offered as an inspiration.


=== missing.py ===

from typing import Any


def MISSING(klass: Any) -> Any:
"""
create a sentinel to indicate a missing instance of a class
:param klass: the class of which an instance is missing
:return: missing class object
"""
g = globals()
missing_klass_name = 
f"_MISSING_{klass.__module__}_{klass.__name__}_MISSING_"
if missing_klass_name not in g:
g[missing_klass_name] = type(
missing_klass_name,
(klass,),
{
"__repr__": lambda x: f"MISSING({klass.__name__})",
}
)
return g[missing_klass_name]()

===


and as a demo:

=== demo_missing.py ===

import pickle


from missing import MISSING


x = MISSING(str)
y = "bar"
print(f"{x!r} == {y!r}: {x == y}")
print(f"{x!r} is {y!r}: {x is y}")
# MISSING(str) == 'bar': False
# MISSING(str) is 'bar': False

with open("object.pickled", "wb") as f:
pickle.dump(x, f)
with open("object.pickled", "rb") as f:
y = pickle.load(f)
print(f"{x!r} == {y!r}: {x == y}")
print(f"{x!r} is {y!r}: {x is y}")
# MISSING(str) == MISSING(str): True
# MISSING(str) is MISSING(str): False


def foo(a: int = MISSING(int), b: int = MISSING(int)):
print(f"{a=} {isinstance(a, int)}")
print(f"{b=} {isinstance(b, int)}")
print(f"{a!r} == {b!r}: {a == b}")
print(f"{a!r} is {b!r}: {a is b}")


foo()
# a=MISSING(int) True
# b=MISSING(int) True
# MISSING(int) == MISSING(int): True
# MISSING(int) is MISSING(int): False

foo(1)
# a=1 True
# b=MISSING(int) True
# 1 == MISSING(int): False
# 1 is MISSING(int): False


class Test:
...


t = MISSING(Test)
print(f"{t=}")
# t=MISSING(Test)

===
___
Python-Dev mailing list -- python-dev@python.org
To unsubscribe send an email to python-dev-le...@python.org
https://mail.python.org/mailman3/lists/python-dev.python.org/
Message archived at 
https://mail.python.org/archives/list/python-dev@python.org/message/42O33BFRJLDFVKX4XSKMZ6VLR7H7GXKP/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Matching syntax and semantics

2020-11-20 Thread Eric Nieuwland
Hi all,

Some days back Mark Shannon posted his view/proposal pattern matching on github.
While reading it I realised an intermediate step between matching and variable 
assignment might do away with part of the discussion.
I wrote it in an issue with the view/proposal 
(https://github.com/markshannon/pattern-matching/issues/1)

Thinking about it a bit longer, it really might be worth exploring the idea 
more, so let me repeat it here:
1. In a pattern the values to match are marked with a special symbol (‘$’, ‘!’ 
or ‘?’ seem candidates).
2. A matching case produces a tuple of matched values. The tuple may be nested 
to reflect the matched structure.
3. The tuple may be deconstructed according to the usual rules.


As an example:

example_value = Example("bar", Embedded(None, "foo"), 42, "baz")

match example_value:
case Example($, Embedded($, "foo"), 42, $) as t:
# t = ("bar”, (None, ), "baz”)
pass
case Example($, Embedded($, "foo"), 42, $) as pre, *rest:
# pre = "bar", rest = ((None, ), "baz”)
pass


alternatively:

match example_value:
case pre, *rest = t = Example($, Embedded($, "foo"), 42, $):
# pre = "bar", rest = ((None, ), "baz”)
# t = ("bar”, (None, ), "baz”)
pass


Just my $0.02


—eric
___
Python-Dev mailing list -- python-dev@python.org
To unsubscribe send an email to python-dev-le...@python.org
https://mail.python.org/mailman3/lists/python-dev.python.org/
Message archived at 
https://mail.python.org/archives/list/python-dev@python.org/message/XSRGCA6L3GYKKHQHZYKMPOM3KTI72STC/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: PEP 622: Arrow for capture patterns

2020-09-08 Thread Eric Nieuwland


On 5 Sep 2020 Ram Rachum  wrote:
> 
> Hi everyone,
> 
> Sorry if this was proposed already. I looked here
> https://www.python.org/dev/peps/pep-0622/#alternatives-for-constant-value-pattern,
> search for "idea to make lookup semantics the default". I saw that a few
> symbols like $ and ? were proposed, and I thought that maybe the annotation
> syntax -> could indicate a capture expression, like so:
> 
>case x:
>match Point(-> a, -> b):
>...
>match -> whatever:
>do_something(whatever)
> 
> I like the arrow because it's easy to imagine the value "entering" the
> variable. What do you think?
> 
> 
> Thanks,
> Ram.


Nice! :)

Combined with keywords that could become:
Point(x -> a, y -> b)

or, mixed with providing values:
Point(x -> a, y=42)

And we wouldn’t need
match -> whatever:
because we already have x, and if x is an expression I’d prefer
case x as whatever:
___
Python-Dev mailing list -- python-dev@python.org
To unsubscribe send an email to python-dev-le...@python.org
https://mail.python.org/mailman3/lists/python-dev.python.org/
Message archived at 
https://mail.python.org/archives/list/python-dev@python.org/message/AFTPEB5R2JMGVLIOOYDCGMMX2QNSTAWJ/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: Pattern matching (alternative to PEP 622)

2020-08-05 Thread Eric Nieuwland

> On 4 Aug 2020, at 14:38, Koos Zevenhoven wrote:
> 
> Hi everyone,
> 
> [ … analysis of design goals and possible solutions, including … ]
> 
> Point3D(x=pi, y=SIX, z=value)

It suddenly struck me that

Point3D(x=pi, y=SIX, z into value)

would quite accurately describe what is being established here.

> [ … goes on … ]
> 
>  matches 
> 
> and that would evaluate to a boolean-like value.

Yes. I’d like that as it separates functionality (pattern matching) from the 
control structure (match statement).

> [ … ]
> 
> Similarly, also
>   point matches main_diagonal_point(pos?)
> should only match if x == y == z — and then bind that value to pos.
> However, one might expect to be able to write the same thing inline as
>   point matches Point3D(pos?, pos?, pos?)
> , so based on that, multiple occurrences of the same binding target should
> ensure equality.
> 
> 
> What about wildcards? If ? were the wildcard, that would mean that
>   point matches main_diagonal_point(?)
> should NOT mean the same as
>   point matches Point3D(?,?,?)
> 
> [ … ]

Clever observations!

> —Koos


—eric
___
Python-Dev mailing list -- python-dev@python.org
To unsubscribe send an email to python-dev-le...@python.org
https://mail.python.org/mailman3/lists/python-dev.python.org/
Message archived at 
https://mail.python.org/archives/list/python-dev@python.org/message/4YPDAYTSJW3AV6FO7PCWXJ74FQST4JLC/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] PEP 622: Structural Pattern Matching -- followup

2020-07-25 Thread Eric Nieuwland
On 24/06/2020 20:38, Guido van Rossum wrote:
> Everyone,
> 
> If you've commented and you're worried you haven't been heard, please=20
> add your issue *concisely* to this new thread. Note that the following=20
> issues are already open and will be responded to separately; please=20
> don't bother commenting on these until we've done so:
> 
> - Alternative spellings for '|'
> - Whether to add an 'else' clause (and how to indent it)
> - A different token for wildcards instead of '_'
> - What to do about the footgun of 'case foo' vs. 'case .foo'
> 
> (Note that the last two could be combined, e.g. '?foo' or 'foo?' to=20
> mark a variable binding and '?' for a wildcard.)

Can we extend the syntax for the match statement from
match_stmt: "match" expression ':' NEWLINE INDENT case_block+ DEDENT
to
match_stmt: "match" expression ['as' NAME] ':' NEWLINE INDENT 
case_block+ DEDENT
with the same meaning as in "with"? 
So the variable with the NAME assumes the value of the expression.

That way I won’t have to use the walrus at every case where I need the full 
result of the expression.
It could even be used to get rid of the walrus_pattern entirely.


Example:

match nested_data[index].attribute as foo:
...
case SomeClass(…):
bar(foo)
…
case AnotherClass(…):
baz(foo)
…
___
Python-Dev mailing list -- python-dev@python.org
To unsubscribe send an email to python-dev-le...@python.org
https://mail.python.org/mailman3/lists/python-dev.python.org/
Message archived at 
https://mail.python.org/archives/list/python-dev@python.org/message/N7DWR5ZNF23HSBRPEPP2GWWKQSYM32AM/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] PEP 622: Structural Pattern Matching -- followup

2020-07-25 Thread Eric Nieuwland



> On 25 Jul 2020, at 03:44, Rob Cliffe  wrote:
> 
> Without arguing for or against allowing a capture variable, IMO rather 
> than syntax like
>match  into :
> it would be far better (and not require a new keyword) to write this as
>with  as match :
> 
> On 24/06/2020 20:38, Guido van Rossum wrote:
>> Everyone,
>> 
>> If you've commented and you're worried you haven't been heard, please=20
>> add your issue *concisely* to this new thread. Note that the following=20
>> issues are already open and will be responded to separately; please=20
>> don't bother commenting on these until we've done so:
>> 
>> - Alternative spellings for '|'
>> - Whether to add an 'else' clause (and how to indent it)
>> - A different token for wildcards instead of '_'
>> - What to do about the footgun of 'case foo' vs. 'case .foo'
>> 
>> (Note that the last two could be combined, e.g. '?foo' or 'foo?' to=20
>> mark a variable binding and '?' for a wildcard.)
>> 

We already have 'with' for contexts.


We already have patterns with 'as':
-   except expression "as" identifier ":"
-   "import" module "as" identifier
-   "with"  expression "as" target


So I think this would be quite confusing.
___
Python-Dev mailing list -- python-dev@python.org
To unsubscribe send an email to python-dev-le...@python.org
https://mail.python.org/mailman3/lists/python-dev.python.org/
Message archived at 
https://mail.python.org/archives/list/python-dev@python.org/message/PDVN3D3FCIM34VGNTEUYTFKYPA57B3Z6/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: Python-Dev Digest, Vol 204, Issue 129

2020-07-25 Thread Eric Nieuwland
On 24/06/2020 20:38, Guido van Rossum wrote:
> Everyone,
> 
> If you've commented and you're worried you haven't been heard, please=20
> add your issue *concisely* to this new thread. Note that the following=20
> issues are already open and will be responded to separately; please=20
> don't bother commenting on these until we've done so:
> 
> - Alternative spellings for '|'
> - Whether to add an 'else' clause (and how to indent it)
> - A different token for wildcards instead of '_'
> - What to do about the footgun of 'case foo' vs. 'case .foo'
> 
> (Note that the last two could be combined, e.g. '?foo' or 'foo?' to=20
> mark a variable binding and '?' for a wildcard.)

Can we extend the syntax for the match statement from
match_stmt: "match" expression ':' NEWLINE INDENT case_block+ DEDENT
to
match_stmt: "match" expression ['as' NAME] ':' NEWLINE INDENT 
case_block+ DEDENT
with the same meaning as in "with"? 
So the variable with the NAME assumes the value of the expression.

That way I won’t have to use the walrus at every case where I need the full 
result of the expression.
It could even be used to get rid of the walrus_pattern entirely.


Example:

match nested_data[index].attribute as foo:
...
case SomeClass(…):
bar(foo)
…
case AnotherClass(…):
baz(foo)
…
___
Python-Dev mailing list -- python-dev@python.org
To unsubscribe send an email to python-dev-le...@python.org
https://mail.python.org/mailman3/lists/python-dev.python.org/
Message archived at 
https://mail.python.org/archives/list/python-dev@python.org/message/IJCTESGMZF6NI7ZTSGLRIXLPA7EN4TF2/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: Python-Dev Digest, Vol 204, Issue 129

2020-07-25 Thread Eric Nieuwland



> On 25 Jul 2020, at 03:44, Rob Cliffe  wrote:
> 
> Without arguing for or against allowing a capture variable, IMO rather 
> than syntax like
> match  into :
> it would be far better (and not require a new keyword) to write this as
> with  as match :
> 
> On 24/06/2020 20:38, Guido van Rossum wrote:
>> Everyone,
>> 
>> If you've commented and you're worried you haven't been heard, please=20
>> add your issue *concisely* to this new thread. Note that the following=20
>> issues are already open and will be responded to separately; please=20
>> don't bother commenting on these until we've done so:
>> 
>> - Alternative spellings for '|'
>> - Whether to add an 'else' clause (and how to indent it)
>> - A different token for wildcards instead of '_'
>> - What to do about the footgun of 'case foo' vs. 'case .foo'
>> 
>> (Note that the last two could be combined, e.g. '?foo' or 'foo?' to=20
>> mark a variable binding and '?' for a wildcard.)
>> 

We already have 'with' for contexts.


We already have patterns with 'as':
-   except expression "as" identifier ":"
-   "import" module "as" identifier
-   "with"  expression "as" target


So I think this would be quite confusing.
___
Python-Dev mailing list -- python-dev@python.org
To unsubscribe send an email to python-dev-le...@python.org
https://mail.python.org/mailman3/lists/python-dev.python.org/
Message archived at 
https://mail.python.org/archives/list/python-dev@python.org/message/U27FYK4U34M7FGDIUTDQZCNAU2MV7UNW/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: PEP 622 constant value syntax idea

2020-07-16 Thread Eric Nieuwland

> From: Baptiste Carvello 
> Subject: [Python-Dev] Re: PEP 622 constant value syntax idea
> 
> What about simply "is", which is already a keyword?
> 
> AFAIK "is" has no meaning as a prefix operator as of now, so hopefully
> it would not make the grammar ambiguous (how can one check that for sure?).
> 
> match color:
>case is RED:
>print("red")
>case is BLUE:
>print("blue")
>case other:
>print(f"unknown color {other}")
> 
> or with Rhodri James' example:
> 
> match value:
>case is x:
>print("value matches")
>case Point(is x, y):
>print("value matches x, y captured")
>case Line(Point(is x1, y1), Point(x2, is y2)):
>print("wouldn't call that pretty, but not ugly either")
> 
> 
> Cheers,
> Baptiste
> 
> P.S.: granted, it could mislead some users into thinking that the
> comparison is done with "is" instead of "=="; but then, patterns are
> special in many ways, users will have to just learn them…

That is exactly why I think you should make the special things special and keep 
the familiar things as you know them.
So constants and variables like they are in other uses and matched 
values/patterns using a special construction/syntax.

And we don’t need the catch all case if we would have the IMHO more familiar:

match Color(…) as color:
   case RED:
   print(f”{color} is red")
   case BLUE:
   print(f”{color} is blue”)
   else:
   print(f"unknown color {color}”)

thus eliminating the whole ‘case ’ issue.
___
Python-Dev mailing list -- python-dev@python.org
To unsubscribe send an email to python-dev-le...@python.org
https://mail.python.org/mailman3/lists/python-dev.python.org/
Message archived at 
https://mail.python.org/archives/list/python-dev@python.org/message/4NTH5H6RX2KTVVJFJUF53UWESJIBCLYS/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: PEP 622 version 2 (Structural Pattern Matching)

2020-07-12 Thread Eric Nieuwland
Rhodri James wrote:

> Eric Nieuwland wrote:
> 
>> Just after I hit ‘send’ it dawned on me it might be preferable to make that
>> 
>> match poly:
>>  p0 = Point(x0, y0)
>>  p1 = Point(x1, y1)
>>  p2 = Point(x2, y2)
>> case Polygon(p0, p1, p2):
>>  …
>> 
>> so the part preceded by ‘match’ is the preparation phase for matching.
>> 
> Are you intending p0, p1 and p2 to be subpatterns rather than object 
> instantiations? That makes me a little twitchy; the difference between what 
> you wrote and:
> 
> match poly:
>   p0 = Point(x0, y0)
>   p1 = Point(x1, y1)
> case Polygon(p0, p1, p2):
>   ... 
> is very easy to miss.
> 

You are perfectly right.
That is why I prefer explicit marking of variables to be bound by matching.
Your example could then become:

match poly:
p0 = Point(x0, \y0)
p1 = Point(\x1, y1)
case Polygon(p0, p1, \p2):
… 

and IMHO it would be very clear what to expect.

An alternative would be to ‘declare’ variables that are to be bound to make 
things even more explicit, like:

match poly:
x1 = to_be_bound_by_matching
y0 = to_be_bound_by_matching
p2 = to_be_bound_by_matching
p0 = Point(x0, y0)
p1 = Point(x1, y1)
case Polygon(p0, p1, p2):
… 

where a better name than ‘to_be_bound_by_matching’ would certainly be needed.

—eric
___
Python-Dev mailing list -- python-dev@python.org
To unsubscribe send an email to python-dev-le...@python.org
https://mail.python.org/mailman3/lists/python-dev.python.org/
Message archived at 
https://mail.python.org/archives/list/python-dev@python.org/message/W6VILFGBO4HJLEAUTSW6SJMNZN352KTJ/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: PEP 622 version 2 (Structural Pattern Matching)

2020-07-12 Thread Eric Nieuwland
Greg Ewing wrote:
> Eric Nieuwland wrote:
> 
>> ...
>> match poly:
>>   p0 = Point(x0, y0)
>>   p1 = Point(x1, y1)
>>   p2 = Point(x2, y2)
>>   case Polygon(p0, p1, p2):
>>   …
>> 
> 
> Interesting idea, but what happens if you don't
>  need any setup?
> Do you have to write
> 
> 
>  match poly:
>  pass
>  case ...
> 
> ?

Yes, that would be the idea.

Unless you would need to setup variables to be bound in the cases, of course.
Without that an if … elif … elif … else structure would be equivalent and 
possibly preferable.
___
Python-Dev mailing list -- python-dev@python.org
To unsubscribe send an email to python-dev-le...@python.org
https://mail.python.org/mailman3/lists/python-dev.python.org/
Message archived at 
https://mail.python.org/archives/list/python-dev@python.org/message/CMDHKH3YPLIQ4WGI4MEL2BQKKVU6DGDE/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: PEP 622 version 2 (Structural Pattern Matching)

2020-07-11 Thread Eric Nieuwland
On 11 Jul 2020, at 21:03, Eric Nieuwland  wrote:

> What I meant to say is that as I read the current PEP text there would be a 
> confusing difference between
> 
>   match poly:
>   case Polygon(Point(x0, y0), Point(x1, y1), Point(x2, y2)):
>   ...
> 
> and
> 
>   p0 = Point(x0, y0)
>   p1 = Point(x1, y1)
>   p2 = Point(x2, y2)
>   match poly:
>   case Polygon(p0, p1, p2):
>   ...
> 
> This would be especially clumsy if I need to match parts in a deep structure.
> It would require me to either write the whole construction as part of the 
> ‘match’ or use ‘match’ nested to drill down to the parts I need.
> 

Just after I hit ‘send’ it dawned on me it might be preferable to make that

match poly:
p0 = Point(x0, y0)
p1 = Point(x1, y1)
p2 = Point(x2, y2)
case Polygon(p0, p1, p2):
…

so the part preceded by ‘match’ is the preparation phase for matching.

This could also resolve the discussion on indentation of the ‘case’ parts and 
the placement of the default matching:

match  [as ]:

case  []:

…
[else:
]

within the preparation statements it would then be allowed to use undefined 
variables as receivers of matched parts.
___
Python-Dev mailing list -- python-dev@python.org
To unsubscribe send an email to python-dev-le...@python.org
https://mail.python.org/mailman3/lists/python-dev.python.org/
Message archived at 
https://mail.python.org/archives/list/python-dev@python.org/message/DOGIGJRL2RBHNGXXH2LZG6QMWTPLHU5J/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: PEP 622 version 2 (Structural Pattern Matching)

2020-07-11 Thread Eric Nieuwland

> On 10 Jul 2020, at 18:28, Jim Baker  wrote:
> 
> On Fri, Jul 10, 2020, 9:16 AM Eric Nieuwland  wrote:
> 
>> On 10 Jul 2020, at 01:51, Jim Baker  wrote:
>> ...
>> Explicit namespacing (if a constant) or using a guard (if a variable) seems 
>> to be the right solution, as Ethan demonstrated earlier. No need for . or ^ 
>> or  \ or ... to disambiguate. Also it seems to me that structural pattern 
>> matching will build on two common usages of namespaces for constants:
>> 
>> 1. Constants used from other modules are almost always used in the module 
>> namespace. Eg, socket.AF_UNIX or signal.SIGTERM.
>> 2. New code often tends to use constants defined within an Enum namespace. 
>> Hopefully we will see more of this convention in usage.
>> 
>> (Very much an aside: Interestingly with the socket module we see both used - 
>> it defines its constants with IntEnum and exports them traditionally. The 
>> namespace specifics it uses with IntEnum._convert_ to make this happen  -- 
>> strictly speaking EnumMeta._convert, not documented, and a bit hard to 
>> follow -- might be possibly debatable, but it works out quite well in 
>> practice in providing backwards compatibility while continuing to work with 
>> a C source of these constants.)
>>  
>> This would also mean
>> case Point(x=\x, y=\y):
>> should be used to obtain x and y from the Point instance.
> 
> This approach makes deeper nesting of the structure much more cumbersome, I 
> think.
> 
> How to match Polygon(Point(x0,y0), Point(x1, y1), Point(x2, y2)) based on its 
> structure?
> And Polygon(Point(x0,y0), p1, Point(x2, y2))?
> 
> 
>  I'm just trying to describe what v2 of the PEP is trying to do and how it 
> then corresponds to a reasonable usage model. Sorry for any confusion.

Yes, I understood. Thank you for that. No apology needed.

> So in your scenario above, Polygon and Point are used as class patterns 
> (https://www.python.org/dev/peps/pep-0622/#class-patterns). Consequently they 
> are treated accordingly and have that nice structural pattern matching 
> quality!

What I meant to say is that as I read the current PEP text there would be a 
confusing difference between

match poly:
case Polygon(Point(x0, y0), Point(x1, y1), Point(x2, y2)):
...

and

p0 = Point(x0, y0)
p1 = Point(x1, y1)
p2 = Point(x2, y2)
match poly:
case Polygon(p0, p1, p2):
...

This would be especially clumsy if I need to match parts in a deep structure.
It would require me to either write the whole construction as part of the 
‘match’ or use ‘match’ nested to drill down to the parts I need.

> Earlier I was discussing constant patterns 
> (https://www.python.org/dev/peps/pep-0622/#constant-value-patterns), which 
> require they be namespaced in some way (a qualified name as it is described 
> in the PEP).

Indeed.
My point is this would be - as far as I know - the first time you need to 
create a namespace to use the value of an already known variable.
This only to allow assignment to variables which I find counterintuitive and 
which IMHO leads to clumsy constructions, as shown above.

So I hope the new and special thing here (i.e. assign matched parts of the 
structure to variables) will not interfere with how we read expressions in 
Python.
A special indicator for the special use case to me seems far easier to 
understand and to teach.

—eric
___
Python-Dev mailing list -- python-dev@python.org
To unsubscribe send an email to python-dev-le...@python.org
https://mail.python.org/mailman3/lists/python-dev.python.org/
Message archived at 
https://mail.python.org/archives/list/python-dev@python.org/message/ZXYKO57S6U5UNQG6Y5IUXIXI54RBV2QD/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: PEP 622 version 2 (Structural Pattern Matching)

2020-07-10 Thread Eric Nieuwland

> On 10 Jul 2020, at 01:51, Jim Baker  wrote:
> 
> 
> On Thu, Jul 9, 2020 at 1:42 PM Eric Nieuwland  <mailto:eric.nieuwl...@gmail.com>> wrote:
> Much of the discussion seems to focus on how to distinguish between a 
> variable as a provider of a value and a variable as receiver of a matched 
> value.
> 
> In normal Python syntax a variable in an expression provides a value, please 
> let’s keep that unchanged.
> 
> For patterns, these are no different than parameters for a function (either a 
> lambda expression or with `def`); or target assignments in unpacking 
> assignments. So just like I wouldn't wonder where `a` and `b` materialized in 
> the parameters for the function definition below
> 
> def sum2(a, b):
>   return a + b 
> 
> I think it will be straightforward to understand this in the context of a 
> `case` using a capture pattern:
> 
> match x:
>   case (a, b): 
>  return a + b
>...
> 
> (This commonality between cases and function definitions is further used in 
> Scala for example, but I don't see that approach for defining an idea of 
> partial functions -- not like functools.partial functions! -- as being that 
> useful in Python.)
> 
> 
> So it seems to me we should explicitly mark a variable to receive a matched 
> value.
> I have seen ‘?’ suggested as a prefix to do this, ‘\’ would also do fine.
> 
> This would solve the single variable issue, too:
> case foo:
> matches the value of ‘foo’, while
> case \foo:
> matches anything and stores it in ‘foo’.
> 
> 
> Explicit namespacing (if a constant) or using a guard (if a variable) seems 
> to be the right solution, as Ethan demonstrated earlier. No need for . or ^ 
> or  \ or ... to disambiguate. Also it seems to me that structural pattern 
> matching will build on two common usages of namespaces for constants:
> 
> 1. Constants used from other modules are almost always used in the module 
> namespace. Eg, socket.AF_UNIX or signal.SIGTERM.
> 2. New code often tends to use constants defined within an Enum namespace. 
> Hopefully we will see more of this convention in usage.
> 
> (Very much an aside: Interestingly with the socket module we see both used - 
> it defines its constants with IntEnum and exports them traditionally. The 
> namespace specifics it uses with IntEnum._convert_ to make this happen  -- 
> strictly speaking EnumMeta._convert, not documented, and a bit hard to follow 
> -- might be possibly debatable, but it works out quite well in practice in 
> providing backwards compatibility while continuing to work with a C source of 
> these constants.)
>  
> This would also mean
> case Point(x=\x, y=\y):
> should be used to obtain x and y from the Point instance.

This approach makes deeper nesting of the structure much more cumbersome, I 
think.

How to match Polygon(Point(x0,y0), Point(x1, y1), Point(x2, y2)) based on its 
structure?
And Polygon(Point(x0,y0), p1, Point(x2, y2))?

___
Python-Dev mailing list -- python-dev@python.org
To unsubscribe send an email to python-dev-le...@python.org
https://mail.python.org/mailman3/lists/python-dev.python.org/
Message archived at 
https://mail.python.org/archives/list/python-dev@python.org/message/VQ25KUKTGWABHK6DYIC6ZEXFSZ2IX7JR/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: PEP 622 version 2 (Structural Pattern Matching)

2020-07-10 Thread Eric Nieuwland

> On 10 Jul 2020, Stefano Borini  wrote:
> 
> Just my 2 cents, I find it kind of annoying that the whole structure
> requires two levels of indentation to actually reach the operational
> code.
> This would be a first in python.
> 
> I would prefer an option akin to if elif elif else where each block is
> only one level deep.


It very much depends on how you read it.

To me the proposed structure is like

with  as :
if   :
…
elif   :
…

and thus not really different

___
Python-Dev mailing list -- python-dev@python.org
To unsubscribe send an email to python-dev-le...@python.org
https://mail.python.org/mailman3/lists/python-dev.python.org/
Message archived at 
https://mail.python.org/archives/list/python-dev@python.org/message/3LCHUK3IV4CXWSFHNROREJQ3WTS2JZ7L/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: PEP 622 version 2 (Structural Pattern Matching)

2020-07-09 Thread Eric Nieuwland
Much of the discussion seems to focus on how to distinguish between a variable 
as a provider of a value and a variable as receiver of a matched value.

In normal Python syntax a variable in an expression provides a value, please 
let’s keep that unchanged.

So it seems to me we should explicitly mark a variable to receive a matched 
value.
I have seen ‘?’ suggested as a prefix to do this, ‘\’ would also do fine.

This would solve the single variable issue, too:
case foo:
matches the value of ‘foo’, while
case \foo:
matches anything and stores it in ‘foo’.

This would also mean
case Point(x=\x, y=\y):
should be used to obtain x and y from the Point instance.
___
Python-Dev mailing list -- python-dev@python.org
To unsubscribe send an email to python-dev-le...@python.org
https://mail.python.org/mailman3/lists/python-dev.python.org/
Message archived at 
https://mail.python.org/archives/list/python-dev@python.org/message/3MC2ZKDVRSDYRBZSYSFDR4M6GKQXITO2/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: PEP 622: Structural Pattern Matching - followup

2020-06-28 Thread Eric Nieuwland
I wrote:
> 
> Guido van Rossum wrote:
> 
>> Eric Nieuwland wrote:
>> 
>>> I have some doubt about the keyword: ‘match' seems to be at odds with
>>> 'for', 'while', 'with', 'if' as it is more of an action.
>>> It's more like 'try' but that statement has a completely different
>>> structure.
>> 
>> Well, 'try' is also an action. :-) Many people have tried to come up with a
>> different keyword here, but nothing has been found that comes even close to
>> the simplicity of match. Plus, several other languages (Scala, Rust) use it
>> too (which is further evidence that it's a natural fit).
> 
> It may also be evidence for not being able to come up with a more accurate 
> keyword.
> 
> Reading through the PEP once more I noticed I was understanding
> 
>   match X:
>   case Y:
>   Z
> 
> as
> 
>   when X:
>   matches Y:
>   Z
> 
> which also to me seems to reflect the close relation to an if-elif-elif… 
> construction.
> 
> This would almost naturally imply the possibility of:
> 
>   when X:
>   matches Y:
>   Z
>   ...
>   else:
>   Q
> 
> And maybe also an additional operator:
> 
>   if X matches Y:
>   Z
> 
> 
>>> Not a native speaker I don't have a reasonable alternative, though.
>> 
>> Me neither, but I speak it quite fluently now, and 'match' really feels
>> like it fits well here.
> 
> Trying ;-)


Thinking of this over the weekend, I think the following might be even more 
flexible and powerful:


when X:
 Y1:
Z1
 Y2:
Z2
…
else:
Q

which would be the same as:

if X  Y1:
Z1
elif X  Y2:
Z2
…
else:
Q

Furthermore

when X:
 Y1 if C1:
Z1
 Y2 if C2:
Z2
…
else:
Q

would be the same as:

if X  Y1 and C1:
Z1
elif X  Y2 and C2:
Z2
…
else:
Q

and so the PEP would need to define:
- the 'when’ keyword
- the 'matches' comparison


___
Python-Dev mailing list -- python-dev@python.org
To unsubscribe send an email to python-dev-le...@python.org
https://mail.python.org/mailman3/lists/python-dev.python.org/
Message archived at 
https://mail.python.org/archives/list/python-dev@python.org/message/Q3GZ3YSI5MDP7DNRWW452STZ6KF6EMBT/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: PEP 622: Structural Pattern Matching

2020-06-25 Thread Eric Nieuwland
Guido van Rossum wrote:

> Eric Nieuwland wrote:
> 
>> I have some doubt about the keyword: ‘match' seems to be at odds with
>> 'for', 'while', 'with', 'if' as it is more of an action.
>> It's more like 'try' but that statement has a completely different
>> structure.
> 
> Well, 'try' is also an action. :-) Many people have tried to come up with a
> different keyword here, but nothing has been found that comes even close to
> the simplicity of match. Plus, several other languages (Scala, Rust) use it
> too (which is further evidence that it's a natural fit).

It may also be evidence for not being able to come up with a more accurate 
keyword.

Reading through the PEP once more I noticed I was understanding

match X:
case Y:
Z

as

when X:
matches Y:
Z

which also to me seems to reflect the close relation to an if-elif-elif… 
construction.

This would almost naturally imply the possibility of:

when X:
matches Y:
Z
...
else:
Q

And maybe also an additional operator:

if X matches Y:
Z


>> Not a native speaker I don't have a reasonable alternative, though.
> 
> Me neither, but I speak it quite fluently now, and 'match' really feels
> like it fits well here.

Trying ;-)___
Python-Dev mailing list -- python-dev@python.org
To unsubscribe send an email to python-dev-le...@python.org
https://mail.python.org/mailman3/lists/python-dev.python.org/
Message archived at 
https://mail.python.org/archives/list/python-dev@python.org/message/MN3TP6UL2QUO6VYIEPUGDGLIREZHYLI2/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-Dev] Re: PEP 622: Structural Pattern Matching

2020-06-24 Thread Eric Nieuwland
Great PEP!

I have some doubt about the keyword: ‘match’ seems to be at odds with ‘for’, 
‘while’, ‘with’, ‘if’ as it is more of an action.
It’s more like ‘try’ but that statement has a completely different structure.

Not a native speaker I don’t have a reasonable alternative, though.
___
Python-Dev mailing list -- python-dev@python.org
To unsubscribe send an email to python-dev-le...@python.org
https://mail.python.org/mailman3/lists/python-dev.python.org/
Message archived at 
https://mail.python.org/archives/list/python-dev@python.org/message/TDWDDAROGWNSARY6AS4O52XAZ44CQDGW/
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-Dev] PEP for adding an sq_index slot so that any object, a or b, can be used in X[a:b] notation

2006-02-09 Thread Eric Nieuwland
Travis Oliphant wrote:
 PEP:  ###
 Title:  Allowing any object to be used for slicing
 [...]
 Rationale

Currently integers and long integers play a special role in slice
notation in that they are the only objects allowed in slice
syntax. In other words, if X is an object implementing the sequence
protocol, then X[obj1:obj2] is only valid if obj1 and obj2 are both
integers or long integers.  There is no way for obj1 and obj2 to
tell Python that they could be reasonably used as indexes into a
sequence.  This is an unnecessary limitation.
 [...]

I like the general idea from an academic point of view.
Just one question: could you explain what I should expect from x[ 
slicer('spam') : slicer('eggs') ]  when slicer implements this 
protocol?
Specifically, I'd like to known how you want to define the interval 
between two objects. Or is that for the sliced/indexed object to 
decide?

--eric

___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] Let's just *keep* lambda

2006-02-05 Thread Eric Nieuwland
On 5 feb 2006, at 18:43, Guido van Rossum wrote:

 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.

 --
 --Guido van Rossum (home page: http://www.python.org/~guido/)

+1

And let's add Wise t the BDFL's title: WBDFL. ;-)

--eric

___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] any support for a methodcaller HOF?

2006-02-04 Thread Eric Nieuwland
Nick Coghlan wrote:
 That's like saying it's not the same because '(x*x def (x)' creates a
 function while '(x*x for x in seq)' creates a generator-iterator. 
 Well,
 naturally - if the expression didn't do something different, what 
 would be the
 point in having it?
;-)
Naturally.  I just wanted to point out it's a beast of another kind, so 
like syntax may not be a good idea.

 The parallel I'm trying to draw is at the syntactic level, not the 
 semantic.
 I'm quite aware that the semantics will be very different ;)

 Yours is

 f = lambda x: x*x

 and it will die by Guido hand...

 In the short term, probably. I'm hoping that the progressive 
 accumulation of
 workarounds like itemgetter, attrgetter and partial (and Alex's 
 suggestion of
 'methodcaller') and the increasing use of function arguments for 
 things like
 sorting and the itertools module will eventually convince Guido that 
 deferring
 expressions is a feature that needs to be *fixed* rather than 
 discarded entirely.

Then how about nameless function/method definition:
def (x):
... usual body ...
produces an unnamed method object
and
def spam(x):

is just
spam = def (x):
...
while our beloved
eggs(lambda x: x*x)
would become
eggs(def(x): return x*x)

--eric

___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] any support for a methodcaller HOF?

2006-02-04 Thread Eric Nieuwland
  Martin v. Löwis wrote:
 I believe that usage of a keyword with the name of a Greek letter also
 contributes to people considering something broken.

QOTW! ;-)

--eric

___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] any support for a methodcaller HOF?

2006-02-04 Thread Eric Nieuwland
Nick Coghlan wrote:
 I believe that usage of a keyword with the name of a Greek letter also
 contributes to people considering something broken.

 Aye, I agree there are serious problems with the current syntax. All 
 I'm
 trying to say above is that I don't believe the functionality itself 
 is broken.

Lambda is not broken, it's restricted to  single calculation and 
therefore of limited use.
Although I wasn't too serious (should had added more signs of that), an 
anonymous 'def' would allow to use the full power of method definition.

 At last count, Guido's stated preference was to ditch the functionality
 entirely for Py3k, so unless he says something to indicate he's 
 changed his
 mind, we'll simply need to continue with proposing functions like
 methodcaller() as workarounds for its absence...

Yep, we'll just have to learn to live without it. :-( / ;-)

--eric

___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] any support for a methodcaller HOF?

2006-02-03 Thread Eric Nieuwland
On 4 feb 2006, at 3:18, Nick Coghlan wrote:
 All I'm suggesting is that a similarly inspired syntax is worth
 considering when it comes to deferred expressions:

def f(x):
  return x*x

 = f = (x*x def (x))

It's not the same, as x remains free whereas in g = [x*x for x in seq] 
x is bound.

Yours is

f = lambda x: x*x

and it will die by Guido hand...
--eric

___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] The path module PEP

2006-02-02 Thread Eric Nieuwland
On 1 feb 2006, at 19:14, BJörn Lindqvist wrote:

 I've submitted an updated version of the PEP. The only major change is
 that instead of the method atime and property getatime() there is now
 only one method named atime(). Also some information about the string
 inheritance problem in Open Issues. I still have no idea what to do
 about it though.

The current PEP still contains some redundancy between properties and 
methods under Specifications:

basename() - name
basename(), stripext() - namebase
splitpath() - parent, name (documented)
I would like to suggest to use only properties and use splitall() to 
obtain a tuple with the complete breakdown of the path.
And may be splitall() could then be renamed to split().

The directory methods mkdir()/makedirs() and rmdir()/removedirs() could 
be unified. To me it seems they only exist because of Un*x details.

my $0.005

--eric
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] Small any/all enhancement

2005-12-28 Thread Eric Nieuwland
I wrote:
 all() can be terminated at the first false element. For very long
 sequences this has important performance benefits. Besides, it makes
 all(seq,pred) the equivalent of pred(seq[0]) and  pred(seq[1]) and
 pred(seq[2]) and ...

then, Martin v. Löwis wrote:

 And so does the version with generator expressions: Alex' expression
 will also terminate with the first false statement; it is equivalent
 to some_objects[0]==0 and some_objects[1]==0 and ...

and Alex Martelli wrote:
 Of course it can -- in both formulations.  genexp's are also computed 
 as needed, only one item at a time: you appear to imply they don't, 
 maybe you're confusing them with list comprehensions.  What I'm asking 
 is, what are the ADVANTAGES of the pred form, that make it worth 
 paying the conceptual cost of having two obvious ways to do one 
 task.

 all(seq,pred) the equivalent of pred(seq[0]) and  pred(seq[1]) and
 pred(seq[2]) and ...

 ...and also the equivalent of all(pred(s) for s in seq) -- which is 
 exactly my problem: I don't like redundant good ways of expressing 
 identical tasks.  The genexp will often be more compact, whenever the 
 'pred' requires a def, a lambda, or something like 
 operator.attrgetter, anyway.

Oops! Right you are. I was a bit too quick after seeing the use of 
map() proposed.

--eric

___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] Small any/all enhancement

2005-12-27 Thread Eric Nieuwland
Alex Martelli wrote:
 On Dec 27, 2005, at 12:45 PM, Valentino Volonghi aka Dialtone wrote:
 ...
 any(iterable, test=bool) and all(iterable, test=bool)
 ...
 any(some_objects, test=operator.attrgetter('some_attribute'))

 Why would that be better than
 any(o.some_attribute for o in some_objects)
 ?

 def zerop(x):
 return x==0

 all(some_objects, zerop)

 and why would that be better than
 all(o==0 for o in some_objects)
 ?

all() can be terminated at the first false element. For very long 
sequences this has important performance benefits. Besides, it makes 
all(seq,pred) the equivalent of pred(seq[0]) and  pred(seq[1]) and 
pred(seq[2]) and ...

___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] Proposed resolutions for open PEP 343 issues

2005-10-27 Thread Eric Nieuwland
Michael Chermside wrote:

 Guido writes:
 I find AttributeError: __exit__ just as informative.

 Eric Nieuwland responds:
 I see. Then why don't we unify *Error into Error?
 Just read the message and know what it means.
 And we could then drop the burden of exception classes and only use 
 the
 message.
 A sense of deja-vu comes over me somehow ;-)

 The answer (and there _IS_ an answer) is that using different exception
 types allows the user some flexibility in CATCHING the exceptions. The
 discussion you have been following obscures that point somewhat because
 there's little meaningful difference between TypeError and
 AttributeError (at least in well-written code that doesn't have
 unnecessary typechecks in it).

Yep. I too would like to have 'SOME flexibility in catching the 
exceptions' meaning I'd like to be able to catch TypeErrors and 
AttributeErrors while not catching what I call ProtocolErrors. The 
simple reason is that in most of my apps TypeErrors and AttributeErrors 
will depend on the runtime situation, while ProtocolErrors will mostly 
be static. So I'll debug for ProtocolErrors and I'll handle runtime 
stuff.

 If there were a significant difference between TypeError and
 AttributeError then Nick and Guido would have immediately chosen the
 appropriate error type based on functionality rather than style, and
 there wouldn't have been any need for discussion.

I got that already. To me it means one of them may be a candidate for 
removal/redefinition.

 Oh yeah, and you can also put extra info into an exception object
 besides just the error message. (We don't do that as often as we
 should... it's a powerful technique.)

Perhaps that needs for propaganda then. I won't dare to suggest 
syntactic sugar ;-)

--eric

___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] Proposed resolutions for open PEP 343 issues

2005-10-26 Thread Eric Nieuwland
Guido van Rossum wrote:

 [Eric are all your pets called Eric? Nieuwland]
 Hmmm... Would it be reasonable to introduce a ProtocolError 
 exception?

 [Guido]
 And which perceived problem would that solve?

 [Eric]
 It was meant to be a bit more informative about what is wrong.

 ProtocolError: lacks __enter__ or __exit__

 That's exactly what I'm trying to avoid. :)

 I find AttributeError: __exit__ just as informative. In either case,
 if you know what __exit__ means, you'll know what you did wrong. And
 if you don't know what it means, you'll have to look it up anyway. And
 searching for ProtocolError doesn't do you any good -- you'll have to
 learn about what __exit__ is and where it is required.

I see. Then why don't we unify *Error into Error?
Just read the message and know what it means.
And we could then drop the burden of exception classes and only use the 
message.
A sense of deja-vu comes over me somehow ;-)

___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] Proposed resolutions for open PEP 343 issues

2005-10-25 Thread Eric Nieuwland
Guido van Rossum wrote:
 It is true though that AttributeError is somewhat special. There are
 lots of places (perhaps too many?) where an operation is defined using
 something like if the object has attribute __foo__, use it, otherwise
 use some other approach.  Some operations explicitly check for
 AttributeError in their attribute check, and let a different exception
 bubble up the stack. Presumably this is done so that a bug in
 somebody's __getattr__ implementation doesn't get masked by the
 otherwise use some other approach branch. But this is relatively
 rare; most calls to PyObject_GetAttr just clear the error if they have
 a different approach available. In any case, I don't see any of this
 as supporting the position that TypeError is somehow more appropriate.
 An AttributeError complaining about a missing __enter__, __exit__ or
 __context__ method sounds just fine. (Oh, and please don't go checking
 for the existence of __exit__ before calling __enter__. That kind of
 bug is found with even the most cursory testing.)

Hmmm... Would it be reasonable to introduce a ProtocolError exception?

--eric

___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] Proposed resolutions for open PEP 343 issues

2005-10-25 Thread Eric Nieuwland
Guido van Rossum wrote:

 On 10/25/05, Eric Nieuwland [EMAIL PROTECTED] wrote:
 Hmmm... Would it be reasonable to introduce a ProtocolError exception?

 And which perceived problem would that solve? The problem of Nick 
 Guido disagreeing in public?

;-)

No, that will go on in other fields, I guess.

It was meant to be a bit more informative about what is wrong.

ProtocolError: lacks __enter__ or __exit__

--eric

___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] Proposed changes to PEP 343

2005-10-07 Thread Eric Nieuwland
Nick Coghlan wrote:

 1. Amend the statement specification such that:

with EXPR as VAR:
BLOCK

 is translated as:

abc = (EXPR).__with__()
exc = (None, None, None)
VAR = abc.__enter__()
try:
try:
BLOCK
except:
exc = sys.exc_info()
raise
finally:
abc.__exit__(*exc)

Is this correct?
What happens to

with 40*13+2 as X:
print X

?

--eric

___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] Proposed changes to PEP 343

2005-10-07 Thread Eric Nieuwland
Nick Coghlan wrote:
 Eric Nieuwland wrote:
 What happens to

 with 40*13+2 as X:
 print X

 It would fail with a TypeError because the relevant slot in the type 
 object
 was NULL - the TypeError checks aren't shown for simplicity's sake.

 This behaviour isn't really any different from the existing PEP 343 - 
 the only
 difference is that the statement looks for a __with__ slot on the 
 original
 EXPR, rather than looking directly for an __enter__ slot.

Hmmm I hadn't noticed that.
In my memory a partial implementation of the protocol was possible.
Thus, __enter__/__exit__ would only be called if they exist.

Oh well, I'll just add some empty methods.

--eric

___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] partition() (was: Remove str.find in 3.0?)

2005-09-01 Thread Eric Nieuwland
Raymond Hettinger wrote:
 I think it's convenient but also rather odd that split() with a static
 string argument was moved from module string to a method in class str,
 while split() with a regexp has remained in module re.

 I don't see what you find odd.  With str and unicode objects being
 builtin, you don't need a separate module.  In contrast, re is a
 stand-alone extension which, of course, requires an import.

That's an implementation oriented view.
IMHO it is all a match-and-cut operation with fixed strings the 
simplest form of match expressions.
 From that point of view the distinction between the two is quite 
arbitrary.
Of course, when turning from principles to daily practice again it is 
quite clear the distinction is useful.

--eric

___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] partition() (was: Remove str.find in 3.0?)

2005-08-30 Thread Eric Nieuwland
Pierre Barbier de Reuille wrote:
 Or you want to have some partition method which accept regular
 expressions:

 head, sep, tail = some_str.partition(re.compile(sep+'.'*offset))

Neat!
+1 on regexps as an argument to partition().

--eric

___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] partition() (was: Remove str.find in 3.0?)

2005-08-30 Thread Eric Nieuwland
On 30 aug 2005, at 17:40, Antoine Pitrou wrote:
 Neat!
 +1 on regexps as an argument to partition().

 It sounds better to have a separate function and call it re.partition,
 doesn't it ?
 By the way, re.partition() is *really* useful compared to re.split()
 because with the latter you don't which string precisely matched the
 pattern (it isn't an issue with str.split() since matching is exact).

Nice, too.
BUT, spam! and eggs.partition(re.compile(!.*d))
more closely resembles xyz.split(), and that is the way things have 
evolved up-to now.

--eric

___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


[Python-Dev] PEP 348 and ControlFlow

2005-08-09 Thread Eric Nieuwland
Dear all,

Sorry to bring this up again, but I think there is an inconsistency in 
PEP 348 in its current formulation.

 From PEP: In Python 2.4, a bare except clause will catch any and all 
exceptions. Typically, though, this is not what is truly desired. More 
often than not one wants to catch all error exceptions that do not 
signify a bad interpreter state. In the new exception hierarchy this 
is condition is embodied by Exception. Thus bare except clauses will 
catch only exceptions inheriting from Exception.

So,  bare except will catch anything that is an Exception. This 
includes GeneratorExit and StopIteration, which contradicts: It has 
been suggested that ControlFlowException should inherit from Exception. 
This idea has been rejected based on the thinking that control flow 
exceptions typically should not be caught by bare except clauses, 
whereas Exception subclasses should be.

To me this means GeneratorExit and StopIteration are to be taken out of 
the Exception subtree. It seems to me rather awkward to put them at the 
same level as Exception and TerminatingException. So there comes the 
old (yeah, I know REJECTED) idea of a ControlFlowException class, right 
next to Exception and TerminatingException:

BaseException
+TerminatingException
+ ...
+ Exception
+ ...
+ ControlFlowException
+ GeneratorExit
+ StopIteration

Is my logic flawed (again ;-)?

--eric
Eric Nieuwland

___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] Terminology for PEP 343

2005-07-01 Thread Eric Nieuwland
Raymond Hettinger wrote:

 With 343 accepted, we can now add __enter__() and __exit__() methods to
 objects.

 What term should describe those objects in the documentation?

Witty objects?

___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] Wishlist: dowhile

2005-06-14 Thread Eric Nieuwland
Nick Coghlan wrote:
 With PEP 315, a do-while loop would look like:

do:
body
while cond:
pass

 But then, I'm reasonably happy with the 'break out of an infinite
 loop' approach, so *shrug*.

 From Programming Languages 101 I remember this construct in Algol 68. 
It was then claimed to be *the* universal loop construct. If that is 
true __and__ it is easy to implement, I'd say +INF for PEP 315.

--eric

___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] Wishlist: dowhile

2005-06-14 Thread Eric Nieuwland
Guido van Rossum wrote:
 On 6/14/05, Eric Nieuwland [EMAIL PROTECTED] wrote:
  From Programming Languages 101 I remember this construct in Algol 68.
 It was then claimed to be *the* universal loop construct. If that is
 true __and__ it is easy to implement, I'd say +INF for PEP 315.

 It's true, but this both dates you (A68 has been dead for several
 decades) and locates you: it was said that A68's popularity was
 inversely proportional to (the square of?) the distance from
 Amsterdam. It also dates and locates me. :-)

Lucky me ;-)

___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] Thoughts on stdlib evolvement

2005-06-06 Thread Eric Nieuwland
Skip Montanaro wrote:
 The main technical challenge seems to be
 backward compatibility.  You need to support both flat (import 
 urllib) and
 packaged namespaces (from www import urllib), possibly within the 
 same
 application.  That is, postulating a www package, if I execute

 import urllib
 from www.urllib import urlopen

 the module-level code should only be executed once, and

 urlopen == urllib.urlopen

 should evaluate to True.

Unless
from __future__ import new_std_library

and we don't allow mixed use within the same module.

--eric

___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] PEP 343 rewrite complete

2005-06-02 Thread Eric Nieuwland
Phillip J. Eby wrote:
 At 10:00 PM 6/1/2005 +0200, Eric Nieuwland wrote:
 Phillip J. Eby wrote:
  -1, too confusing.

 A matter of taste, I guess. IMHO 'with' secretly handling exceptions 
 is
 confusing.

 It doesn't secretly handle them; it simply gets access to them, which 
 is an entirely different thing.

 By confusing, I mean that it is not clear from your construct what 
 exceptions are caught by the 'except' clause, due to its structural 
 layout.  It's also not clear whether the __enter__/__exit__ of EXPR 
 wrap BLOCK1 only, or both BLOCK1 and BLOCK2.  These aspects are 
 confusing because whatever decision you make about the semantics, 
 someone will have to *remember* them, as opposed to being 
 unambiguously represented by the block structure.

 By contrast, if you remove the except: clause from your construct, it 
 is clear that BLOCK1 is what is wrapped, and there is no possible 
 confusion about who sees what exceptions.  Exceptions inside the block 
 are communicated to __exit__, exceptions outside (including those in 
 the 'with' statement itself) are not.

OK. This forwarding (is that the proper expression here?) of an 
exception to __exit__ is what I meant by 'secretly handling'.

If everybody agrees I'll write
with EXPR as VAR:
try:
BLOCK1
except EXCEPTION:
BLOCK2
instead. Seems a waiste to me, though.
I was thinking about 'try EXPR [as VAR]:' as a 'try' that handles 
uncaught exceptions by forwarding it to EXPR's __exit__ method. No 
confusion with me.

--eric

___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] PEP 343 rewrite complete

2005-06-02 Thread Eric Nieuwland

On 2 jun 2005, at 22:12, Phillip J. Eby wrote:

 At 10:04 PM 6/2/2005 +0200, Eric Nieuwland wrote:
 I was thinking about 'try EXPR [as VAR]:' as a 'try' that handles 
 uncaught exceptions by forwarding it to EXPR's __exit__ method. No 
 confusion with me.

 No doubt.  However, it's not obvious what happens to an exception in 
 EXPR; surely it can't be passed to EXPR's __exit__ method.  So, is it 
 handled by the try, or does it pass out of the block?  Whichever 
 answer you give, there is somebody who will think the opposite.  And 
 this is precisely the ambiguity I've been talking about.

 In contrast, a 'with' unmixed with 'try' is absolutely unambiguous as 
 to which except: clauses handle what exceptions where.

slap forehead I never thought of that! Now I see what you mean.
I could only save my idea by stating the scope of 'try' only starts 
after the ':', but that seems too artificial.

--eric

___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] PEP 343 rewrite complete

2005-06-01 Thread Eric Nieuwland
Nice going! But ...

Could we extend the 'try' syntax for this instead of introducing 
'with'? If I look at the translation it an augmented 'try'.
with EXPR as VAR:
BLOCK1
except EXCEPTION:
BLOCK2
could then be translated to
abc = EXPR
exc = (None, None, None)
VAR = abc.__enter__()
try:
try:
BLOCK1
except EXCEPTION:
BLOCK2
except:
exc = sys.exc_info()
raise
finally:
abc.__exit__(*exc)


Can the 'throw()' method be renamed 'raise()'? IMHO that makes much 
clearer what happens.

Same thing with 'GeneratorExit', 'StopGeneration' more closely matches 
'StopIteration'.

--eric

___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] PEP 343 rewrite complete

2005-06-01 Thread Eric Nieuwland
Eric Nieuwland wrote:

 If I look at the translation it an augmented 'try'.
   with EXPR as VAR:
   BLOCK1
   except EXCEPTION:
   BLOCK2

Oops, that should read:

try EXPR as VAR:
BLOCK1
except EXCEPTION:
BLOCK2

--eric

___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] PEP 343 rewrite complete

2005-06-01 Thread Eric Nieuwland
Phillip J. Eby wrote:
 At 08:46 PM 6/1/2005 +0200, Eric Nieuwland wrote:
 If I look at the translation it an augmented 'try'.
 with EXPR as VAR:
 BLOCK1
 except EXCEPTION:
 BLOCK2
 could then be translated to

 -1, too confusing.

A matter of taste, I guess. IMHO 'with' secretly handling exceptions is 
confusing.

 Can the 'throw()' method be renamed 'raise()'? IMHO that makes much
 clearer what happens.

 No, 'raise' is a reserved word.  It would have to be 'raise_()'.  -0.

My bad. Should have thought about that.

 Same thing with 'GeneratorExit', 'StopGeneration' more closely matches
 'StopIteration'.

 StopIteration is raised the *other* way, so closely matching isn't 
 really a benefit.  -1.

Yep! Misread that one.

--eric

___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] PEP 344: Exception Chaining and Embedded Tracebacks

2005-05-17 Thread Eric Nieuwland
Guido van Rossum wrote:
 Consider

 try:
 BLOCK
 except EXCEPTION, VAR:
 HANDLER

 I'd like to see this translated into

 try:
 BLOCK
 except EXCEPTION, VAR:
 __context = VAR
 try:
 HANDLER
 except Exception, __error:
 __error.__context__ = __context
 raise

If I interpret the above translation correctly, then:
 try:
 BLOCK1
 except EXCEPTION1, VAR1:
 try:
 BLOCK2
 except EXCEPTION2, VAR2:
 HANDLER

with exceptions occuring in BLOCK1, BLOCK2 and HANDLER would result in 
HANDLER's exception with __context__ set to BLOCK1's exception and 
BLOCK2's exception would be lost.

--eric

___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] PEP 343 - Abstract Block Redux

2005-05-15 Thread Eric Nieuwland
Shane Hathaway wrote:
 Here is example A, a non-looping block statement using try:

 text = 'diamond'
 for fn in filenames:
 try opening(fn) as f:
 if text in f.read():
 print 'I found the text in %s' % fn
 break

That's a pretty way to write it!
Would it be possible to extend the 'try' syntax in this way?
It would certainly stress the fact that this construct includes 
exception handling.

--eric

___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] Merging PEP 310 and PEP 340-redux?

2005-05-11 Thread Eric Nieuwland
Guido van Rossum wrote:
 class locking:
 def __init__(self, lock): self.lock = lock
 def __enter__(self): self.lock.acquire()
 def __exit__(self, *args): self.lock.release()

 class opening:
 def __init__(self, filename): self.filename = filename
 def __enter__(self): self.f = open(self.filename); return self.f
 def __exit__(self, *args): self.f.close()\

 And do EXPR as VAR: BLOCK would mentally be translated into

 itr = EXPR
 VAR = itr.__enter__()
 try: BLOCK
 finally: itr.__exit__(*sys.exc_info()) # Except sys.exc_info() isn't
 defined by finally

In this example locking's __enter__ does not return anything.
Would
do EXPR:
BLOCK
also be legal syntax?


-eric

___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] PEP 340: Deterministic Finalisation (new PEP draft, either a competitor or update to PEP 340)

2005-05-09 Thread Eric Nieuwland
Greg Ewing wrote:
 Ron Adam wrote:
 There seems to be some confusion as to weather or
 not 'for's will do finalizing.  So I was trying to stress I think
 regular 'for' loops should not finalize. They should probably give an
 error if an object with an try-finally in them or an __exit__ method.

 But if the for-loop can tell whether the iterator
 needs finalizing or not, why not have it finalize
 the ones that need it and not finalize the ones
 that don't? That would be backwards compatible,
 since old for-loops working on old iterators would
 work as before.

That's why I suggested to have the behaviour depend on what is passed 
in as EXPR.

for VAR in EXPR:
BLOCK

could be translated to:

__cleanup = False
__itr = EXPR
if not isinstance(__itr,iterator):
__itr = iter(__itr)
__cleanup = True
while True:
try:
VAR = __itr.next()
except StopIteration:
break
BLOCK
if __cleanup:
__itr.__exit__()

Which would require isinstance(__itr,iterator) or equivalent to act as 
a robust test on iterators.
I'll leave 'for' with an 'else' clause as an exercise to the reader.

--eric

___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] PEP 340: Deterministic Finalisation (new PEP draft, either a competitor or update to PEP 340)

2005-05-08 Thread Eric Nieuwland
Josiah Carlson wrote:
 Eric Nieuwland [EMAIL PROTECTED] wrote:
 I don't know. Using 'del' in that place seems ackward to me.
 Why not use the following rule:
  for [VAR in] EXPR:
  SUITE
 If EXPR is an iterator, no finalisation is done.
 If EXPR is not an iterator, it is created at the start and destroyed 
 at
 the end of the loop.

 You should know why that can't work.  If I pass a list, is a list an
 iterator?  No, but it should neither be created nor destroyed before or
 after.

I suggested to create AN ITERATOR FOR THE LIST and destroy that at the 
end. The list itself remains untouched.

--eric

___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] PEP 340: Deterministic Finalisation (new PEP draft, either a competitor or update to PEP 340)

2005-05-08 Thread Eric Nieuwland
Josiah Carlson wrote:
 The argument over whether blocks should loop, I believe has been had;
 they should.  The various use cases involve multi-part transactions and
 such.

Then it is not so much looping but more pushing forward the state of 
the state of the block's life-cycle?
This might by a good moment to consider life-cycle support a la PROCOL.

--eric

___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] PEP 340: Deterministic Finalisation (new PEP draft, either a competitor or update to PEP 340)

2005-05-07 Thread Eric Nieuwland
Nick Coghlan wrote:

 [...]
 The whole PEP draft can be found here:
 http://members.iinet.net.au/~ncoghlan/public/pep-3XX.html
 [...]
 Used as follows::

  for del auto_retry(3, IOError):
  f = urllib.urlopen(http://python.org/;)
  print f.read()

I don't know. Using 'del' in that place seems ackward to me.
Why not use the following rule:
for [VAR in] EXPR:
SUITE
If EXPR is an iterator, no finalisation is done.
If EXPR is not an iterator, it is created at the start and destroyed at 
the end of the loop.

--eric

___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] Pre-PEP: Unifying try-except and try-finally

2005-05-06 Thread Eric Nieuwland
Guido van Rossum wrote:
 try_stmt: 'try' ':' suite
 (
 except_clause ':' suite)+
 ['else' ':' suite] ['finally' ':' suite]
 |
 'finally' ':' suite
 )

 There is no real complexity in this grammar, it's unambiguous, it's an
 easy enough job for the code generator, and it catches a certain class
 of mistakes (like mis-indenting some code).

Fair enough. Always nice to have some assistence from the system.

--eric

___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] PEP 340: Breaking out.

2005-05-05 Thread Eric Nieuwland
Ronald Oussoren wrote:
 What's bothering me about the proposed semantics is that block
 statement behaves like a loop while most use cases do no looping 
 whatsoever.
 Furthermore the it doesn't feel like loop either. In all three 
 examples on this page I'd assume
 that the break would break out of the for loop.

I'm bothered the same way.
IMHO control constructs should be very clear. No implicit looping, 
conditionals etc.
Especially since the main reason to have this whole discussion is about 
resource management.
The main pattern of use I have in mind is:

resource = grab/allocate/open/whatever(...)
try:
do something possibly with the resource
except ...:
...
finally:
...
resource.release/deallocate/close/whatever()

This is linear. No looping whatsoever. And easily translated to a 
simple language construct and a protocol:

class resource(object):
def __init__(self,...):
# store resource parameters
def __acquire__(self):
# whatever it takes to grab the resource
def __release__(self):
# free the resource

res = resource(...)
acquire res:
do something possibly with the resource
except ...:
...
finally:
...

The resource is automagically released at the end of the 'acquire' 
block (keyword up for other proposals :-)
An alternative syntax could also be allowed:

acquire resource(...) as res:
...etc...

Then 'res' would be undefined after the 'acquire' block.

--eric

___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] anonymous blocks

2005-04-19 Thread Eric Nieuwland
Guido van Rossum wrote:
tri = self.subcalculation(The quick brown fox jumps over the lazy 
dog)
self.disentangle(0x40, tri, self.indent+1)

IMO this is clearer, and even shorter!
But it clutters the namespace with objects you don't need. So the 
complete equivalent would be more close to:
	tri = self.subcalculation(The quick brown fox jumps over the lazy 
dog)
	self.disentangle(0x40, tri, self.indent+1)
	del tri
which seems a bit odd to me.

If we apply this to the anonymous block problem, we may end up finding
lambda the ultimate compromise -- like a gentleman in the back of my
talk last week at baypiggies observed (unfortunately I don't know his
name).
It wasn't me ;-) It seems this keeps getting back at you. Wish I had 
thought of this argument before.

--eric
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] @decoration of classes

2005-03-26 Thread Eric Nieuwland
Given the ideas so far, would it possible to:
def meta(cls):
...
@meta
class X(...):
...
??
--eric
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] @decoration of classes

2005-03-26 Thread Eric Nieuwland
On 26 mrt 2005, at 21:36, Josiah Carlson wrote:
Eric Nieuwland [EMAIL PROTECTED] wrote:
Given the ideas so far, would it possible to:
def meta(cls):
...
@meta
class X(...):
...
It is not implemented in Python 2.4.  From what I understand, making it
happen in Python 2.5 would not be terribly difficult.  The question is
about a compelling use case.  Is there a use where this syntax is
significantly better, easier, etc., than an equivalent metaclass?  
Would
people use the above syntax if it were available?

What would you use the above syntax to do?
Well, I can imagine using
@meta(MyMetaClass)
class MyClass(...):
...
instead of
class MyClass(...):
__metaclass__ = MyMetaClass
...
Somehow, it seems more aesthetic to me.
--eric
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Fwd: [Python-Dev] docstring before function declaration

2005-03-21 Thread Eric Nieuwland
Nicholas Jacobson wrote:
IIRC, Guido once mentioned that he regretted not
setting function docstrings to come before the
function declaration line, instead of after.
[ examples deleted ]
I think that commenting the function before its
declaration, at the same tabbed point, increases the
code's readability.
What do you think about making this change at some
point (e.g. Python 3000)?  Or if not, then having the
option to toggle to this layout?
Please don't. All class attributes are declared within the class. 
Pulling out the docstring would make it an exception. The current 
situation is very clear and easy to explain to newbies.

If you feel the current position of the docstring may be the first 
attribute's docstring, insert a newline at the proper positions to 
separate the two. It works for me.

--eric
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] comprehension abbreviation (was: Adding any() and all())

2005-03-15 Thread Eric Nieuwland
Martin v. Löwis wrote:
That's not the full syntax. The full syntax is
[ test for exprlist in testlist list-iter-opt ]
where
test can be an arbitrary expression: and, or, lambda, +, -, ...
exprlist can be a list of expression, except for boolean and
relational expressions (but I think this is further constrained
semantically)
testlist list a list of tests
list-iter-opt is optional, and can be another for or if block
Aren't these names a bit mixed up w.r.t. what's in that position? As 
far as I know
test is not a test but a function as it produces any value not just 
True/False
exprlst is a list of names, not arbitrary expressions
testlist is anything which will produce an iterator

Or so I've understood so far.
So a more complex example is
   [ lambda a: a[x]+y*z for x,y in A for z in B if x  z]
I'm schocked ;-)
--eric
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] func.update_meta (was: @deprecated)

2005-03-14 Thread Eric Nieuwland
Neat! But please add something to the __doc__ so we can also see it was 
changed. E.g.
	self.__doc__ = other.__doc__ + os.linesep + *** deprecated ***

On 12 mrt 2005, at 5:25, Nick Coghlan wrote:
I like update_meta
Patch against current CVS added to SF with the behaviour:
  def update_meta(self, other):
self.__name__ = other.__name__
self.__doc__ = other.__doc__
self.__dict__.update(other.__dict__)
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] comprehension abbreviation (was: Adding any() and all())

2005-03-14 Thread Eric Nieuwland
Gareth McCaughan wrote:
I'd like it, and my reason isn't just to save typing.
There are two reasons.
  1 Some bit of my brain is convinced that [x in stuff if condition]
is the Right Syntax and keeps making me type it even though
I know it doesn't work.
  2 Seeing [x for x in stuff if condition] triggers my internal
duplicated-stuff alarm, and it's distracting, in the same sort
of way as it's distracting in C or C++ seeing
The full syntax is:
	[ f(x) for x in seq if pred(x) ]
being allowed to write 'x' instead of 'identity(x)' is already a 
shortcut, just as dropping the conditional part.

Remember we're doing set theory stuff here. IMHO we should follow its 
notation conventions as much as we can.

--eric
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] Rationale for sum()'s design?

2005-03-14 Thread Eric Nieuwland
Guido van Rossum wrote:
I think the conclusion should be that sum() is sufficiently
constrained by backwards compatibility to make fixing it impossible
before 3.0. But in 3.0 I'd like to fix it so that the 2nd argument is
only used for empty lists.
Which is not unlike the get() method of dicts. So may be the default 
should be None?

___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] Re: [Pythonmac-SIG] The versioning question...

2004-12-28 Thread Eric Nieuwland
Martin v. Löwis wrote:
Eric Nieuwland wrote:
Would it be an idea to submit a PEP for extending the 'import' 
keyword?
No. Normally, packages should aim for backwards compatibility, so that
applications would only want to specify a minimum version, such as
import xml
assert xml.version_info  (0,8,2)
If you really want side-by-side installation of different versions,
and a mechanism to select between them, the package could support
import xml_0_8_2 as xml
IOW, import-as should be sufficient for what you want to achieve.
Unless you are doing comparison tests, where it would be nice to be 
able to state in a generic way that the new implementation should not 
change answers. May be something like:

import spam[1] as spamnext  # next version
import spam[0]  as spamnow  # current version
assert spamnow.Ni() == spamnext.Ni()
--eric
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


[Python-Dev] Re: [Pythonmac-SIG] The versioning question...

2004-12-27 Thread Eric Nieuwland
Hi all,
On 27 dec 2004, at 19:27, Chris Barker wrote:
Robin has added versioning to the latest wxPython, and I. for one am 
ecstatic. It works great for me. I am generally using 2.5.3, but have 
2.4.2 installed, and a number of my apps depend  on it (on Linux 
anyway,  it's pretty useless on OS-X)

It's great to be able to put:
import wxversion
wxversion.select(2.4)
At the top of my apps, and know that they'll use the version of 
wxPython I tested against.
Would it be an idea to submit a PEP for extending the 'import' keyword?
I can imagine it to be like:
import spam version 1
import foo version 2, 4
import bar version 7, 1, 6
with version numbers consisting of some fixed maximum of parts and the 
version number parts not given might be wildcards.

We could then have a per module version system like:
.../
spam/
1.0.1/
... [version 1.0.1 stuff in here]
1.5.7/
... [version 1.5.7 stuff in here]
there should be nothing else in the module directory, except for a 
mechanism to further support versioning.
Default behaviour of 'import spam' would be to select the most recent 
version. We might want to override that by pointing to some other 
version. This might be achieved using a symbolic link/alias/shortcut to 
the directory of that version (spam/current - spam/1.0.1).
More like the directory/module method would be to allow for a 
__version__.py file in 'spam'. Content of this file is to be 
determined, but I think it should at least something like __current__ 
or __version__ to act as the pointer to the current version.

--eric
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com