Re: [Python-ideas] Trigonometry in degrees

2018-06-08 Thread Adam Bartoš
Steven D'Aprano wrote:
> On Fri, Jun 08, 2018 at 10:53:34AM +0200, Adam Bartoš wrote:
>> Wouldn't sin(45 * DEG) where DEG = 2 * math.pi / 360 be better that
>> sind(45)? This way we woudn't have to introduce new functions. (The
problem
>> with nonexact results for nice angles is a separate issue.)
>
> But that's not a separate issue, that's precisely one of the motives for
> having dedicated trig functions for degrees.
>
> sind(45) (or dsin(45), as I would prefer) could (in principle) return
> the closest possible float to sqrt(2)/2, which sin(45*DEG) does not do:
>
> py> DEG = 2 * math.pi / 360
> py> math.sin(45*DEG) == math.sqrt(2)/2
> False
>
> Likewise, we'd expect cosd(90) to return zero, not something not-quite
> zero:
>
> py> math.cos(90*DEG)
> 6.123031769111886e-17
>
>
>
> That's how it works in Julia:
>
> julia> sind(45) == sqrt(2)/2
> true
>
> julia> cosd(90)
> 0.0
>
>
> and I'd expect no less here. If we can't do that, there probably
> wouldn't be much point in the exercise.

But if there are both sin and dsin, and you ask about the difference
between them, the obvious answer would be that one takes radians and the
other takes degrees. The point that the degrees version is additionally
exact on special values is an extra benefit. It would be nice to also fix
the original sin, or more precisely to provide a way to give it a
fractional multiple of pi. How about a special class PiMultiple that would
represent a fractional multiple of pi?

PI = PiMultiple(1)
assert PI / 2 == PiMultiple(1, 2)
assert cos(PI / 2) == 0
DEG = 2 * PI / 360
assert sin(45 * DEG) == sqrt(2) / 2

Best regards,
Adam Bartoš
___
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] Trigonometry in degrees

2018-06-08 Thread Adam Bartoš
Wouldn't sin(45 * DEG) where DEG = 2 * math.pi / 360 be better that
sind(45)? This way we woudn't have to introduce new functions. (The problem
with nonexact results for nice angles is a separate issue.)

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


Re: [Python-ideas] A real life example of "given"

2018-05-30 Thread Adam Bartoš
A side comment:

> potential_updates = {
> y: potential_update
> for x in need_initialization_nodes
> for y in [x, *x.synthetic_inputs()]
> given potential_update = command.create_potential_update(y)
> if potential_update is not None}

Probably, I would write

@make_dict
def potential_updates():
for x in need_initialization_nodes:
for y in [x, *x.synthetic_inputs()]:
potential_update = command.create_potential_update(y)
if potential_update is not None:
yield y, potential_update

If such pattern covered a lot of examples, even some syntax sugar could be
added. For example:

foo[0].potential_updates = dict(_) from:
for x in need_initialization_nodes:
for y in [x, *x.synthetic_inputs()]:
potential_update = command.create_potential_update(y)
if potential_update is not None:
yield y, potential_update

where

 from:


would be equivalent to

def _():

_ = _()


Best regards,
Adam Bartoš
___
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] Keyword declarations

2018-05-17 Thread Adam Bartoš
On Wed May 16 20:53:46 EDT 2018, Steven D'Aprano wrote:
> On Wed, May 16, 2018 at 07:24:19PM +0200, Adam Bartoš wrote:
>> Hello,
>>
>> I have yet another idea regarding the the clashes between new keywords
and
>> already used names. How about introducing two new keywords *wink* that
>> would serve as lexical keyword/nonkeyword declarations, similarly to
>> nonlocal and global declarations?
>>
>> def f():
>> nonkeyword if
>> if = 2 # we use 'if' as an identifier
>> def g():
>> keyword if
>> if x > 0: pass # now 'if' again introduces a conditional
statement
>
> This is absolutely no help at all for the common case that we have an
> identifier that is a keyword and want to use it as a keyword in the same
> block. For example, we can currently write:
>
> try:
>value = data.except_
> except:
> value = data.missing()
>
> say. We're using "except_" because the data comes from some external
> interface where it uses "except", but we can't use that because its a
> keyword.

If it was possible to consider any syntactical block for the declarations,
this use case could be handled like:

try:
nonkeyword except
value = data.except
except:
value = data.missing()

Alternatively, data.except could be allowed even without a declaration as
another idea suggests. There are syntactical positions where it is easy to
distinguish between a keyword and an identifier, there are positions where
it is harder, or even impossible due to limitations on the parser
complexity. So both ideas may be viewed as complementary, and the base case
of my proposal would be just a per module opt out from a keyword, so it is
easier to fix such module when a new keyword is introduced in the language.


> I also challenge to think about how you will document the complicated
> rules for when you can and can't use keywords as names, especially think
> about explaining them to beginners:
>
> def spam(None=42):
> print(None)  # What will this print?
> x = None  # Fine, but what does it do?
> None = 999  # Is this an error or not?

None is a different kind of keyword. Ordinary keywords that make the
statements of the language have no value, so 'x = if' makes no sense. On
the other hand, None, True, and False are singleton values (like Ellispsis
and NotImplemented) that are additionally protected from be redefined,
which makes them similar to keywords. I think that the barrier for adding
new keyword constants is even higher than the barrier for adding new
ordinary keywords, and so may be omited when trying to solve the
keyword/identifier problem.

nonkeyword None # SyntaxError: a keyword constant 'None' cannot be an
identifier


> Remember the KISS principle.

It seemed to me that the syntactical block based declarations are quite
simple in principle, but you are right, there are many issues.


Best regards,
Adam Bartoš
___
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] Keyword declarations

2018-05-16 Thread Adam Bartoš
Hello,

I have yet another idea regarding the the clashes between new keywords and
already used names. How about introducing two new keywords *wink* that
would serve as lexical keyword/nonkeyword declarations, similarly to
nonlocal and global declarations?

def f():
nonkeyword if
if = 2 # we use 'if' as an identifier
def g():
keyword if
if x > 0: pass # now 'if' again introduces a conditional statement

This allows to have a name as both identifier and keyword in a single
module, and since it's lexical, it could be in principle syntax-highlighted
correctly.

When a new keyword is added to the list of standard keywords like 'given'
or 'where', a module that uses the name as identifier could be easily fixed
by a global declaration 'nonkeyword given'. Maybe even exception messages
pointing to this could be added. If 'nonkeyword keyword' is allowed, we can
also fix code using the name 'keyword' as an identifier, but doing so in
the global scope couldn't be undone.

On the other hand, new language features depending on new keywords could be
made provisionary by not adding the keywords to the standard list, so
people who would like to use them would need to opt in by e.g. 'keyword
given'. Surely, this provisional mechanism isn't robust at all since new
features may just extend the usage of current keywords.

Declaring a keyword that has no meaning in the language would result in an
exception:

keyword foo # SyntaxError: undefined keyword 'foo'

It should be possible to use a keyword as a parameter name without need to
declare it in the surrounding scope, the local declaration would suffice:

# nonkeyword if # not needed
def f(if=3): # ok
nonkeyword if

Other option is to interpret parameters always as nonkeywords or to raise a
special syntax error when a keyword occurs at a place of a formal parameter
(similarly to 'def f(x): nonlocal x').

Clearly, even if this proposal diminished the cost of adding new keywords,
the cost would still be high.


Best regards,
Adam Bartoš
___
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] allow overriding files used for the input builtin

2017-09-29 Thread Adam Bartoš
Hello,

it seems that there are two independent issues – a way to temporarily
replace all sys.std* streams, and a way to use the special interactive
readline logic for arbitrary terminal-like file. I thought that OP's
concern was the latter. In that case shouldn't there just be a way to
produce an IO object f whose .readline() (or other special method) does
this and has an optional prompt argument? The OP's code would become

with open_terminal('/dev/tty') as f:
name = f.readline(prompt='Name? ')

It seems to me that changing the rather specialized input() function is
wrong in both cases. For me input() is just a short way to read from the
standard input, usually interactively – the same way print is a short way
to write to the standard output. IIRC there was even proposal to remove
input() in favor of direct use of sys.stdin.readline() at time of Python
3000 redesign.

Regards, Adam Bartoš
___
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 532: A circuit breaking operator and protocol

2016-11-11 Thread Adam Bartoš
Just a small suggestion:

wouldn't it be better to use adjectives instead of verbs for proposed
builtin names and their variants?

existing(foo) else bar
non_None(foo) else bar

instead of

exists(foo) else bar
is_not_None(foo) else bar

Regards,
Adam Bartoš
___
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 530: Asynchronous Comprehensions

2016-09-04 Thread Adam Bartoš
Hello,

will await be allowed also in the "if" part of comprehensions? And what
about the "in" part? (e.g. if I'm not mistaken, we may have an asynchronous
function returning an asynchronous iterator.)

Regards,
Adam Bartoš
___
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] Fix default encodings on Windows

2016-08-12 Thread Adam Bartoš
*On Fri Aug 12 11:33:35 EDT 2016, *

*Random832 wrote:*> On Wed, Aug 10, 2016, at 15:08, Steve Dower wrote:
>>* That's the hope, though that module approaches the solution differently
*>>* and may still uses. An alternative way for us to fix this whole thing
*>>* would be to bring win_unicode_console into the standard library and use
*>>* it by default (or probably whenever PYTHONIOENCODING is not specified).
*>
> I have concerns about win_unicode_console:
> - For the "text_transcoded" streams, stdout.encoding is utf-8. For the
> "text" streams, it is utf-16.

UTF-16 it the "native" encoding since it corresponds to the wide chars used
by Read/WriteConsoleW. The UTF-8 is used just as a signal for the consumers
of PyOS_Readline.

> - There is no object, as far as I can find, which can be used as an
> unbuffered unicode I/O object.

There is no buffer just on those wrapping streams because the bytes I have
are not in UTF-8. Adding one would mean a fake buffer that just decodes and
writes to the text stream. AFAIK there is no guarantee that sys.std*
objects have buffer attribute and any code relying on that is incorrect.
But I inderstand that there may be such code and we may want to be
compatible.


> - raw output streams silently drop the last byte if an odd number of
> bytes are written.

That's not true, it doesn't write an odd number of bytes, but returns the
correct number of bytes written. If only one byte is given, it raises a
ValueError.


> - The sys.stdout obtained via streams.enable does not support .buffer /
> .buffer.raw / .detach
> - All of these objects provide a fileno() interface.

Is this wrong? If I remember, I provide it because of some check -- maybe
in input() -- to be viewed as a stdio stream.


> - When using os.read/write for data that represents text, the data still
> should be encoded in the console encoding and not in utf-8 or utf-16.

I don't know what to do with this. Generally I wouldn't use bytes to
communicate textual data.


Regards,
Adam Bartoš
___
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] Fix default encodings on Windows

2016-08-11 Thread Adam Bartoš
Eryk Sun wrote:

> IMO, Python needs a C implementation of the win_unicode_console
> module, using the wide-character APIs ReadConsoleW and WriteConsoleW.
> Note that this sets sys.std*.encoding as UTF-8 and transcodes, so
> Python code never has to work directly with UTF-16 encoded text.
>
>
The transcoding wrappers with 'utf-8' encoding are used just as a work
around the fact that Python tokenizer cannot use utf-16-le and that the
readlinehook machinery is unfortunately bytes-based. The tanscoding wrapper
just has encoding 'utf-8' and no buffer attribute, so there is no actual
transcoding in sys.std* objects. It's just a signal for PyOS_Readline
consumers, and the transcoding occurs in a custom readline hook. Nothing
like this would be needed if PyOS_Readline was replaced by some Python API
wrapper around sys.readlinehook that would be Unicode string based.

Adam Bartoš
___
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 525: Asynchronous Generators

2016-08-09 Thread Adam Bartoš
Hello,

when I was reading the PEP, it surprised me that return is not allowed in
an async generator. You can transparently decompose an ordinary function,
and yield from was added to be able to do the same with generators, so it
seems natural to be able to decompose async generators the same way – using
(await) yield from and return.

I found the explanation in the section about async yield from, but maybe a
link to that section might be added as explanation why return produces a
SyntaxError.

In ideal world it seems that the transition from ordinary functions to
generators and the transition from ordinary functions to async functions
(coroutines) are orthogonal, and async gnerators are the natural
combination of both transitions. I thing this is true despite the fact that
async functions are *implemented* on top of generators. I imagine the
situation as follows: being a generator adds an additional output channel –
the one leading to generator consumer, and being an async function adds an
additional output channel for communication with the scheduler. An async
generator somehow adds both these channels.

I understand that having the concepts truly ortogonal would mean tons of
work, I just think it's pity that something natural doesn't work only
because of implementation reasons. However, introducing async generators is
an important step in the right way. Thank you for that.

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