Re: [Python-ideas] An alternative to PEP 572's Statement-Local Name Bindings

2018-03-04 Thread Nathan Schneider
On Sun, Mar 4, 2018 at 11:04 PM, Chris Angelico  wrote:

> On Mon, Mar 5, 2018 at 2:49 PM, Mike Miller 
> wrote:
> > Yes, thanks:
> >
> > [ f(y), g(y) for x, h(x) as y in things ]
> >
> >
> > Dyslexics untie!
>
> :)
>
> Hmm. The trouble here is that a 'for' loop is basically doing
> assignment. When you say "for x, h(x) as y in things", what Python
> does is (simplified):
>
> _it = iter(things)
> while not StopIteration:
> x, (h(x) as y) = next(_it)
> ... loop body ...
>
> So what you're asking for is something that doesn't behave like an
> assignment target, but just does its own assignment. Bear in mind,
> too, that "x = next(_it)" is very different from "x, = next(_it)";
> which one is "x, (h(x) as y) = next(_it)" more like?
>
>
If I understood Mike's proposal correctly it was to allow "," to mean
'given' in this context when followed by EXPRESSION "as" VARIABLE, rather
than its usual iterable-unpacking meaning.

But I think this would cause confusion. Suppose `things` contains
pair-tuples. Then you could have

[ f(y), g(y) for x1, x2, h(x1) as y in things ]

which makes it look like (x1, x2, h(x1)) go together rather than just (x1,
x2).

Nathan
___
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] An alternative to PEP 572's Statement-Local Name Bindings

2018-03-04 Thread Chris Angelico
On Mon, Mar 5, 2018 at 2:49 PM, Mike Miller  wrote:
> Yes, thanks:
>
> [ f(y), g(y) for x, h(x) as y in things ]
>
>
> Dyslexics untie!

:)

Hmm. The trouble here is that a 'for' loop is basically doing
assignment. When you say "for x, h(x) as y in things", what Python
does is (simplified):

_it = iter(things)
while not StopIteration:
x, (h(x) as y) = next(_it)
... loop body ...

So what you're asking for is something that doesn't behave like an
assignment target, but just does its own assignment. Bear in mind,
too, that "x = next(_it)" is very different from "x, = next(_it)";
which one is "x, (h(x) as y) = next(_it)" more like?

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] An alternative to PEP 572's Statement-Local Name Bindings

2018-03-04 Thread Mike Miller

Yes, thanks:

[ f(y), g(y) for x, h(x) as y in things ]


Dyslexics untie!


On 2018-03-04 19:45, Chris Angelico wrote:
___
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] An alternative to PEP 572's Statement-Local Name Bindings

2018-03-04 Thread Chris Angelico
On Mon, Mar 5, 2018 at 2:39 PM, Mike Miller  wrote:
>
> On 2018-03-03 16:51, Greg Ewing wrote:
>>>
>>> 2018-03-03 8:40 GMT+01:00 Nick Coghlan :

pairs = [(f(y), g(y)) for x in things with bind(h(x)) as y]
>>
>>
>> I don't mucn like "with bind(h(x)) as y" because it's kind of
>> like an abstraction inversion -- you're building something
>> complicated on top of something complicated in order to get
>> something simple, instead of just having the simple thing
>> to begin with. If nothing else, it has a huge runtime cost
>> for the benefit it gives.
>
>
> Reading this thread I was thinking that the assignment part was happening
> too far away from where the action was and came up with this variant:
>
> [ f(y), g(y) for x, y as h(x) in things ]
>
> Plus or minus an extra set of parentheses for clarity.

Did you mean:

[ f(y), g(y) for x, h(x) as y in things ]

? Elsewhere in Python, "a as b" takes "a" and binds it to the name
"b". Otherwise, I'm not sure what you meant.

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] An alternative to PEP 572's Statement-Local Name Bindings

2018-03-04 Thread Mike Miller


On 2018-03-03 16:51, Greg Ewing wrote:

2018-03-03 8:40 GMT+01:00 Nick Coghlan :

   pairs = [(f(y), g(y)) for x in things with bind(h(x)) as y]


I don't mucn like "with bind(h(x)) as y" because it's kind of
like an abstraction inversion -- you're building something
complicated on top of something complicated in order to get
something simple, instead of just having the simple thing
to begin with. If nothing else, it has a huge runtime cost
for the benefit it gives.


Reading this thread I was thinking that the assignment part was happening too 
far away from where the action was and came up with this variant:


[ f(y), g(y) for x, y as h(x) in things ]

Plus or minus an extra set of parentheses for clarity.

-Mike
___
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] Split, slice, join and return "syntax" for str

2018-03-04 Thread Steven D'Aprano
On Sun, Mar 04, 2018 at 12:11:16PM -0800, Michel Desmoulin wrote:

> But, first, they are not common enough so that it's hard to do:
> 
> spam = docs.python.org"
> eggs = 'wiki.' + '.'.join(spams.split('.')[1:])

In a more realistic case, the delimiter is not necessarily a constant, 
nor will you always want to replace the first item.

So you would be writing:

delimiter.join(
spam.split(delimiter)[:n-1] + 
['wiki'] + spam.split(delimiter)[n+1:]
)


Suddenly it's a lot less attractive to be typing out each time.

It is a good candidate for a helper function:

def replace_field(string, delimiter, position, new, start=0, end=None):
fields = string[start:end].split(delimiter)
fields[position] = new
string = (string[:start] + delimiter.join(fields) 
  + ('' if end is None else string[end:]))
return string

That's not the most efficient implementation, and it isn't thoroughly 
tested/debugged, but it ought to be good enough for casual use.

Personally, if this were available as a string method I think I'd use 
this quite frequently, certainly more often than I use some other string 
methods like str.partition.


> It's not that long to type, and certainly is not happening in every
> single script you do.

Speak for yourself :-)

No, not literally every script. (If that were the requirement to be a 
string method, strings would have no methods.) But I think it is common 
enough that I'd be happy for it to be a string method.


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


Re: [Python-ideas] Split, slice, join and return "syntax" for str

2018-03-04 Thread Steven D'Aprano
On Sun, Mar 04, 2018 at 01:44:20PM -0500, Clint Hepner wrote:

> -1. I see no compelling reason to overload __getitem__ to provide a synonym 
> for the split method. 
> 
> eggs = "wiki." + spam.split('.')[1:]

Fair point. Neither do I. But your next comment:

> Besides, you can already make such replacements more efficiently with
> 
> eggs = spam.replace('docs', 'wiki')

is not suitable, because it assumes that the substring "docs" appears 
only once in the string.

In a more realistic example, you don't know what the string contains, 
only that it is delimited by dots and that you want to replace the n-th
field (whatever it contains) with "wiki".



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


Re: [Python-ideas] Split, slice, join and return "syntax" for str

2018-03-04 Thread Michel Desmoulin
Even if replace would be a better fit, I can see why doing those 3
operations in one row can be valuable.

But, first, they are not common enough so that it's hard to do:

spam = docs.python.org"
eggs = 'wiki.' + '.'.join(spams.split('.')[1:])

It's not that long to type, and certainly is not happening in every
single script you do.

But let's say for the sake of argument you do a lot of cmd parsing, with
a lot of split and join. Just make a helper:

def rearrange(string, sep=None, start=None, stop=None, step=None):
return sep.join(string.split(sep)[start:stop:step])

And then you can do:

spam = docs.python.org"
eggs = 'wiki.' + rearrange(spam, '.', 1)

Simple, easy, no need to change Python.



Le 04/03/2018 à 09:59, Andrés Delfino a écrit :
> Hi!
> 
> I was thinking: perhaps it would be nice to be able to quicky split a
> string, do some slicing, and then obtaining the joined string back.
> 
> Say we have the string: "docs.python.org ", and
> we want to change "docs" to "wiki". Of course, there are a ton of
> simpler ways to solve this particular need, but perhaps str could have
> something like this:
> 
> spam = "docs.python.org "
> eggs = "wiki." + spam['.'][1:]
> print(eggs) #wiki.python.org 
> 
> A quick implementation to get the idea and try it:
> 
> class Mystr(str):
>     def __getitem__(self, item):
>     if isinstance(item, str):
>     return Mystr_helper(self, item)
>     else:
>     return super().__getitem__(item)
> 
> class Mystr_helper:
>     def __init__(self, obj, sep):
>     self.obj = obj
>     self.sep = sep
>     def __getitem__(self, item):
>     return self.sep.join(self.obj.split(self.sep)[item])
> 
> What are your thoughts?
> 
> Greetings from Argentina.
> 
> 
> ___
> 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] Split, slice, join and return "syntax" for str

2018-03-04 Thread Clint Hepner

> On 2018 Mar 4 , at 12:59 p, Andrés Delfino  wrote:
> 
> Hi!
> 
> I was thinking: perhaps it would be nice to be able to quicky split a string, 
> do some slicing, and then obtaining the joined string back.
> 
> Say we have the string: "docs.python.org", and we want to change "docs" to 
> "wiki". Of course, there are a ton of simpler ways to solve this particular 
> need, but perhaps str could have something like this:
> 
> spam = "docs.python.org"
> eggs = "wiki." + spam['.'][1:]
> print(eggs) #wiki.python.org

-1. I see no compelling reason to overload __getitem__ to provide a synonym for 
the split method. 

eggs = "wiki." + spam.split('.')[1:]

Besides, you can already make such replacements more efficiently with

eggs = spam.replace('docs', 'wiki')

or, for more complex replacements, 

eggs = re.sub('^docs', 'wiki', spam)

--
Clint
___
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] An alternative to PEP 572's Statement-Local Name Bindings

2018-03-04 Thread Robert Vanden Eynde
> I know Guido is on record as not wanting to allow both "for name in
> sequence" and "for name = expr" due to that being a very subtle distinction
> between iteration and simple assignment (especially given that Julia uses
> them as alternate spellings for the same thing), but I'm wondering if it may
> be worth considering such a distinction in *with statements*, such that we
> allowed "with name = expr" in addition to "with cm as name" (where "name =
> expr" is just an ordinary assignment statement that doesn't trigger the
> context management protocol).
>
> The related enhancement to comprehensions would then be to allow with
> clauses to be interleaved between the for loops and the if statements, such
> that you could write things like:
>
> pairs = [(f(y), g(y)) for x in things with y = h(x)]
> contents = [f.read() for fname in filenames with open(fname) as f]
>
> while still preserving the property where comprehensions can be correctly
> interpreted just by converting each of the clauses to the corresponding
> statement form.
>
> Even without the "with name = expr" change, allowing with clauses in
> comprehensions would let you do (by way of a suitably defined "bind" CM):
>
> pairs = [(f(y), g(y)) for x in things with bind(h(x)) as y]

Including standard "with open(...) as f" context management in list
comprehensions would also be a good idea, I think it's in the same
idea as including : allowing both statements (imperative programming)
and list comprehension (more "functional"). The same story goes for
exceptions :

for x in range(5):
   try:
   yield f(x)
   except Exception:
   yield 0

isn't "refactorable" as a list comprehension like :

[try f(i) except Exception: 0 for x in range(5)]

But I think that would cover another subject :)

But if the "with =" syntax is accepted for simple assignment, it could
indeed introduce a confusion compared to the "with as" in context
management, and having a complete different keyword (or punctuation)
is maybe be better.

As a symmetry, we could also introduce the "with =" syntax in normal
statement :P that'd do a normal assignement, although that's be
probably stupid because normal assignements works well.

Robert
___
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] An alternative to PEP 572's Statement-Local Name Bindings

2018-03-04 Thread Robert Vanden Eynde
> What the heck, if it was good enough for PL/1...

It would still be parsable indeed.

A keyword available in a context would then be something new in the language.

> Choice of syntax is important, though. It's all very well
> to come up with an "insert syntax here" proposal that has
> some big obvious benefit, but if you can't actually come
> up with a pleasing syntax for it, then it won't fly. So
> it makes sense to consider potential syntaxes along with
> other aspects of a proposal.

Of course the syntax is very important, that's why we make a list of
pro's and con's about each syntax.
However, people also want to know if the feature is useful for a lot of users.

So, should we do that list somewhere ? :)
___
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] An alternative to PEP 572's Statement-Local Name Bindings

2018-03-04 Thread Robert Vanden Eynde
> Robert Vanden Eynde wrote:
>>
>> But I think that the implementation of print(y with y = x + 1) would
>> be more close to next(y for y in [ x+1 ])
>
>
> WHy on earth should it be? Expanding that gives you a generator
> containing a loop that only executes once that is immediately run
> to yield exactly one value. Why bother with all that overhead?
>

You're probably right.
___
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] Split, slice, join and return "syntax" for str

2018-03-04 Thread Andrés Delfino
Hi!

I was thinking: perhaps it would be nice to be able to quicky split a
string, do some slicing, and then obtaining the joined string back.

Say we have the string: "docs.python.org", and we want to change "docs" to
"wiki". Of course, there are a ton of simpler ways to solve this particular
need, but perhaps str could have something like this:

spam = "docs.python.org"
eggs = "wiki." + spam['.'][1:]
print(eggs) #wiki.python.org

A quick implementation to get the idea and try it:

class Mystr(str):
def __getitem__(self, item):
if isinstance(item, str):
return Mystr_helper(self, item)
else:
return super().__getitem__(item)

class Mystr_helper:
def __init__(self, obj, sep):
self.obj = obj
self.sep = sep
def __getitem__(self, item):
return self.sep.join(self.obj.split(self.sep)[item])

What are your thoughts?

Greetings from Argentina.
___
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] Class autoload

2018-03-04 Thread Nick Coghlan
On 4 March 2018 at 03:42, Chris Angelico  wrote:

> On Sun, Mar 4, 2018 at 4:12 AM, Jamesie Pic  wrote:
> >
> > Hello everybody,
> >
> > I thought perhaps we could allow the usage of a "new" keyword to
> instanciate
> > an object, ie:
> >
> >obj = new yourmodule.YourClass()
> >
> > In this case, it would behave the same as from yourmodule import
> YourClass;
> > obj = YourClass(), except that it wouldn't need to be imported. This
> would
> > also eliminate the need to manage an import list at the beginning of a
> > script in most case.
> >
>
> This actually has nothing to do with classes. You can currently write this:
>
> import yourmodule
> obj = yourmodule.YourClass()
>
> without any sort of 'new' keyword. So presumably what you're asking
> for is a way to avoid typing the 'import' statement.
>
> That's something that's come up every once in a while. Usually for the
> benefit of throwaway scripts and the interactive interpreter, because
> in serious applications, a single 'import' line is a small price to
> pay for the clarity. You may want to dig through the archives to find
> the arguments for and against this sort of automated import.
>
> > I'm really not proud of this idea but PHP has had autoload for years and
> > when i open scripts with hundred lines of imports it makes me think
> Python
> > could do something about this.
>
> A hundred lines of imports? Surely an exaggeration... or possibly you
> have a whole lot of "from module import name" lines that could become
> a single "import module" line.


Excessive numbers of top level imports in a single file are also frequently
a sign that that module has too many responsibilities and could stand to be
split up (either as multiple parallel APIs, or by splitting out a lower
level helper library) for ease of comprehension. Those split up API
implementations can then be aggregated back together into a single public
API (e.g. in a package `__init__.py` file)

As Chris has noted, function level lazy imports are also already supported,
and we've (begrudgingly) made the import system work harder to successfully
resolve circular imports in recent releases (they're also much harder to
dead lock in Python 3 than they were in Python 2, since we also switched
over to per-module import locks).

Cheers,
Nick.

-- 
Nick Coghlan   |   ncogh...@gmail.com   |   Brisbane, Australia
___
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] Class autoload

2018-03-04 Thread Stephen J. Turnbull
Jamesie Pic writes:

 > obj = new yourmodule.YourClass()

I don't understand what this is good for.  Keeping up with PHP is not
something that is a goal for Python.  Borrowing useful features is
definitely an idea, but you need to explain why it's useful.

I also don't understand why you call this "autoload", and claim it
avoids importing the module.  The "autoload" I'm familiar with from
Lisp is actually lazy loading: the object's name is marked as loadable
and from where, but the module is loaded only if the name is
dereferenced.  In most implementations, the whole module is imported,
as it is in Python.  Experience says that modules are generally
coherent, with lots of internal cross-references: you'll need the
whole thing eventually anyway.  I would guess this is true in PHP as
well, as it is a very dynamic language too AIUI.

Various barriers you'll need to clear:

(1) Niggle: "new" already means something in Python that is different
from initialization.  (class.__new__ vs. class.__init__)  You
*could* ignore that and use "new" for this feature anyway, but you
probably want to choose a different name.

(2) Adding keywords is *very* hard to do in Python, for several
non-technical reasons.  This is not going to clear the bar.

(3) Without *very* major changes to Python, you're not going to be
able to import just that class (unless it's the entire content of
the module).  You have to import the whole module into memory
anyway.

 > While i understand it would be harder to make it memory efficient,

I'm not sure what you mean by "memory efficient".  If you mean
multiple copies of the module in memory, that won't happen anyway:
Python knows what it has imported already, and when using the "from
module import anothername as alias" syntax, the second time you import
"from module", it reuses the existing copy in memory even though
"module" isn't known in that namespace.  This "new" syntax would be
treated the same way.

If you mean only importing enough of the module to make YourClass
work, I don't think that will ever happen.  That would require a kind
of global knowledge of the application that is difficult, and maybe
theoretically impossible, in a language as dynamic as Python.

 > but this is python not go,

I have no idea what that is supposed to mean.

 > and also this sort feature could be easily optional,

It's not optional for your successors in your job, though.  They have
to read your code.  We care about readers of code (in general, not
just your successor) more than we care about writers of code.  Why
make things more complicated for them?  There has to be a real win in
expressiveness or power here.  I don't see it yet.

We know what happens when you concentrate on making everything as
terse as possible: Perl.  Python will never be a good imitation of
Perl; there's no real point in trying since we already have Perl if we
want it.

 > also, it might even help against circular import issues

You're just blowing smoke here, aren't you?  I see no reason why this
would help with circular import issues due to the semantics of import
in Python: you get the whole module whether you need it or not.
Without the global application analysis mentioned previously, "new"
can't know that it's OK to omit any of the imports.

 > Yes i know it's sad php has this feature and python does not

As several other posters say, it's not clear this is a feature at all
from Python's point of view.  I don't think it is.  I've never used
PHP so I have no idea what it's good for, but I suppose the same holds
for it as for Perl: Python doesn't try to be PHP, so any feature that
PHP has but Python doesn't needs to be justified on its merits *in
Python*, not in PHP.

 > and again i'm not proud to say this but it's true.

It's a fact.  There's nothing to be ashamed of.  Diversity is good.

Regards,

___
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] An alternative to PEP 572's Statement-Local Name Bindings

2018-03-04 Thread Stephen J. Turnbull
Nick Coghlan writes:

 > pairs = [(f(y), g(y)) for x in things with y = h(x)]
 > contents = [f.read() for fname in filenames with open(fname) as f]

This is horrible.  I think Julia is just weird: in normal English we
do distinguish between equality and membership.  "x in y" is a very
different statement from "x = y".  I think even Guido would come
around to the view if it were implemented (assuming not "over his dead
body").  But the semantics of "x = y" and "y as x" in English are both
pretty much the copula.  It's hard enough to stay aware that there be
dragons in a context manager; if "with" could denote a simple (local)
binding, it would require conscious effort.

 > Even without the "with name = expr" change, allowing with clauses in
 > comprehensions would let you do (by way of a suitably defined "bind" CM):
 > 
 > pairs = [(f(y), g(y)) for x in things with bind(h(x)) as y]

This is *much* better.  But suppose you wanted to have *several*
bindings.  Would this syntax allow "destructuring" of tuples (as the
for clause will do):

pairs = [(f(x) + g(y), f(x) - g(y)) for w, z in pairs_of_things
 with bind((h(w), k(z)) as (x, y)]

?  This is a question about all the proposals for local binding, I
think.

Steve

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


Re: [Python-ideas] An alternative to PEP 572's Statement-Local Name Bindings

2018-03-04 Thread Stephen J. Turnbull
Soni L. writes:

 > [(lambda y: (f(y), g(y)))(h(x)) for x in things] ?

MicroLisp?
___
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 572 version 2: Statement-Local Name Bindings

2018-03-04 Thread Stephen J. Turnbull
Chris Angelico writes:

 > > So what happens to rejected alternatives when the PEP itself is rejected?
 > > ;)
 > >
 > 
 > Algebraically, they must be accepted. Right?

That's not how de Moivre's laws work. ;-)


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