for / while else doesn't make sense

Steven D'Aprano steve at pearwood.info
Sun May 22 11:19:04 EDT 2016


On Mon, 23 May 2016 12:15 am, Jon Ribbens wrote:

> On 2016-05-21, Chris Angelico <rosuav at gmail.com> wrote:
>> On Sat, May 21, 2016 at 10:35 AM, Jon Ribbens
>><jon+usenet at unequivocal.co.uk> wrote:
>>> To be fair, I'm very sympathetic to that argument. I think programming
>>> languages should never magically produce floats out of nowhere unless
>>> the programmer has explicitly done "import float" or "float('3.23')"
>>> or somesuch. They're misunderstood so often that any convenience
>>> they provide is outweighed by the danger they bring.
>>>
>>> "(1/10) * (1/10) * 10 != (1/10)" anyone? I was distinctly unhappy with
>>> the Python 3 "2/3 ~= 0.6666" thing and regard it as a very retrograde
>>> change.
>>
>> The trouble is, what SHOULD 2/3 return?
>>
>> * An integer? Makes a lot of sense to a C programmer. Not so much to
>> someone who is expecting a nonzero value. This isn't terrible (hey,
>> Python 2 managed with it no problem), but will definitely confuse a
>> number of people.
> 
> Yes, it should return an integer - and not because I think Python
> should behave like C on principle, but because:
> 
>         Explicit is better than implicit.
>         Simple is better than complex.
>         Complex is better than complicated.
> 
> and floats are complicated.

How is this any better though? Complicated or not, people want to divide 1
by 2 and get 0.5. That is the functional requirement. Furthermore, they
want to use the ordinary division symbol / rather than having to import
some library or call a function.

Having 1/2 return 0 (as Python 2 does by default) doesn't make the language
any less complicated. It doesn't avoid the complexity of floats, it merely
breaks the principle of least surprise, and forces the programmer to add
what they consider to be an unnecessary ".0" to one or the other of the
operands.

Swapping to a base-10 float will be numerically even worse than the binary
floats we use now. Swapping to rationals add complexity and performance
issues. So whatever you do, there is complexity and annoyance.


>> * A float? That's what we currently have. Not perfect, but it's going
>> to confuse less people than 0 will.
> 
> That's a trap for those people though - it lulls them into thinking
> that they understand what's going on, when in fact they don't,
> because they don't understand floats, because almost nobody
> understands floats. So they don't understand their program, and
> - even worse - they don't know that they don't understand it.

And how does forcing them to write 1.0/2 solve that?

Or (hypothetical) float.divide(1, 2) if you want to be even more
explicit :-)


> Programming languages should do what they are told, and very little
> more.

Okay, now I'm confused. How is 1/2 returning 0.5 the language not doing what
you've told it to do?


> They should not wander off on surprising jaunts of their own 
> invention out of the control of the programmer. It should be possible
> to know and understand the language, or at least the subset of it
> that you are likely to need for your everyday purposes. Floats are
> generally not understood, so they shouldn't be suddenly turning up
> un-called for.

How are they uncalled for? 

> Python generally sticks to this idea very well, which is one of the
> things that I think make it an excellent programming language, so it
> is a shame that in the Python 2 to Python 3 change when mistakes were
> being rectified, a new one was introduced.

*shrug*

I've programmed in Python using classic integer division and true division,
and in my experience and opinion, classic division is a real pain to work
with. You're forever having to cast things to float or write .0 literals
just to convince the interpreter to do division the way you expect.

I suppose some language some day might experiment with swapping the
operators, so that a/b is integer division and a//b is true division.



-- 
Steven




More information about the Python-list mailing list