Re: Are the critiques in "All the things I hate about Python" valid?

2018-02-26 Thread Ian Kelly
On Mon, Feb 26, 2018 at 8:55 PM, Ian Kelly  wrote:
> On Mon, Feb 26, 2018 at 8:09 PM, Steven D'Aprano
>  wrote:
>> Yes you did: "the last second of every year" is always 23:59:59 of 31st
>> December, and it is always the same time and date "every year".
>
> Except when it's 23:59:60 or 23:59:61 (which hasn't yet happened but could).

Actually, after doing some reading on the subject just now, I learned
that double leap seconds don't actually exist! They were accidentally
invented by the drafters of the ANSI C standard and later propagated
to the POSIX standard and the ANSI SQL standard.

https://www.ucolick.org/~sla/leapsecs/timescales.html#UTC

So the actual last second of the year must always be one of 23:59:58,
23:59:59 or 23:59:60.

(Hint: although we've never had a negative leap second to date, don't
schedule your database update for 23:59:59 if you want to ensure that
it actually happens.)
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Are the critiques in "All the things I hate about Python" valid?

2018-02-26 Thread Chris Angelico
On Tue, Feb 27, 2018 at 2:55 PM, Ian Kelly  wrote:
> On Mon, Feb 26, 2018 at 8:09 PM, Steven D'Aprano
>  wrote:
>> Yes you did: "the last second of every year" is always 23:59:59 of 31st
>> December, and it is always the same time and date "every year".
>
> Except when it's 23:59:60 or 23:59:61 (which hasn't yet happened but could).

Unless you use a leap smear to avoid it.

ChrisA
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Are the critiques in "All the things I hate about Python" valid?

2018-02-26 Thread Chris Angelico
On Tue, Feb 27, 2018 at 12:18 PM, Rick Johnson
 wrote:
> On Tuesday, February 20, 2018 at 5:45:36 PM UTC-6, Steven D'Aprano wrote:
>> On Tue, 20 Feb 2018 12:42:23 -0800, Rick Johnson wrote:
>>
>> > For instance, if the age is queried many times a second,
>> > it would be a much wiser design to set-up an event that
>> > will advance the age at the end of the last second of
>> > every year
>>
>> Do you really mean to say that everybody in the world has
>> their birthday on January 1st? We're not racehorses you
>> know.
>
>
> No, silly rabbit. I was thinking about the problem from a
> _relative_ perspective, whereas you were thinking about the
> problem from a _global_ perspective. Neither perspective is
> wrong.
>
> If you read my exact words again:
>
> "a much wiser design to set-up an event that will advance
> the age at the end of the last second of every year"
>
> ...you'll notice that i mentioned no specific date.
>
> Therefore, "the last day of the year" (in relativistic
> terms) is 11:59:59PM on the calendar day which _precedes_
> the day of the month for which you were born.
>
> So, for instance: if your birthday is January 25th 1969, the
> last second of the last day of your _first_ year is January
> 24th 1970 @ 11:59:59PM. And the last second of the last day
> of your _second_ year is January 24th 1971 @ 11:59:59PM. And
> so forth...
>
> Does this make sense?

Yes! It does. All you have to do is run a batch job in exactly the
very last second of *every single day*. Totally not a problem!

Have you ever run a database in your life?

Tip: When you're in a hole, stop digging.

ChrisA
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Are the critiques in "All the things I hate about Python" valid?

2018-02-26 Thread Ian Kelly
On Mon, Feb 26, 2018 at 8:09 PM, Steven D'Aprano
 wrote:
> Yes you did: "the last second of every year" is always 23:59:59 of 31st
> December, and it is always the same time and date "every year".

Except when it's 23:59:60 or 23:59:61 (which hasn't yet happened but could).
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Are the critiques in "All the things I hate about Python" valid?

2018-02-26 Thread Steven D'Aprano
On Mon, 26 Feb 2018 17:18:38 -0800, Rick Johnson wrote:

[...]
> So, for instance: if your birthday is January 25th 1969, the last second
> of the last day of your _first_ year is January 24th 1970 @ 11:59:59PM.
> And the last second of the last day of your _second_ year is January
> 24th 1971 @ 11:59:59PM. And so forth...
> 
> Does this make sense?

Indeed it does, and frankly, the Racehorse scheme is better.

At least with the Racehorse scheme, you only need to update the database 
once a year, at midnight on the new year, which hopefully is the quietest 
time of the year for you. You can lock access to the database, run the 
update, and hopefully be up and running again before anyone notices 
anything other than a minor outage.

With your scheme, well, I can think of a few ways to do it, none of which 
are good. A database expert might be able to think of some better ideas, 
but you might:

1. Run a separate scheduled job for each record, which does nothing but 
advance the age by one at a certain time, then sleep for a year. If you 
have ten million records, you need ten million scheduled jobs; I doubt 
many scheduling systems can cope with that many jobs. (But I welcome 
correction.)

Also, few scheduling systems guarantee that jobs will execute at 
*precisely* the time you expect. If the system is down at the time the 
job was scheduled to run, they may never run at all. So there is likely 
to be a lag between when you want the records updated, and when they 
actually are updated.

No, using scheduled jobs is fragile, and expensive.


Plan 2: have a single job that does nothing but scan the database, 
continuously in a loop, and if a record's birthdate is more than a year 
in the past, and hasn't been updated in the last year, update the age by 
one.

Actually, I think this sucks worse than the ten-million-scheduled-jobs 
idea. Hopefully it will be obvious why this idea is so awful.


Plan 3: have a trigger that runs whenever a record is queried or 
accessed. If the birthdate is more than a year in the past, and it has 
been more than a year since the last access, then update the age.

This at least doesn't *entirely* suck. But if you're going to go to the 
trouble of doing this on *every* access to the record, isn't it simpler 
to just make the age a computed field that calculates the age when needed?

The cost of computing the age is not that expensive, especially if you 
store the birthdate in seconds. It's just a subtraction, maybe followed 
by a division if you want the age in years. It hardly seems worthwhile 
storing the age as a pre-computed integer if you then need a cunning 
scheme to possibly update that integer on every access to the record.

I think that Rick's "optimization" here is a perfect example of 
pessimisation (making a program slower in the mistaken belief that you're 
making it faster). To quote W.A. Wulf:

"More computing sins are committed in the name of efficiency (without 
necessarily achieving it) than for any other single reason — including 
blind stupidity."



-- 
Steve

-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Are the critiques in "All the things I hate about Python" valid?

2018-02-26 Thread Steven D'Aprano
On Mon, 26 Feb 2018 17:18:38 -0800, Rick Johnson wrote:

> On Tuesday, February 20, 2018 at 5:45:36 PM UTC-6, Steven D'Aprano
> wrote:
>> On Tue, 20 Feb 2018 12:42:23 -0800, Rick Johnson wrote:
>>
>> > For instance, if the age is queried many times a second, it would be
>> > a much wiser design to set-up an event that will advance the age at
>> > the end of the last second of every year
>>
>> Do you really mean to say that everybody in the world has their
>> birthday on January 1st? We're not racehorses you know.

[...]
 
> If you read my exact words again:
> 
> "a much wiser design to set-up an event that will advance the age at
> the end of the last second of every year"

Oh, you mean the exact same words already quoted above?

> ...you'll notice that i mentioned no specific date.

Yes you did: "the last second of every year" is always 23:59:59 of 31st 
December, and it is always the same time and date "every year". Just 
because you didn't explicitly state the name of a month doesn't mean you 
didn't implicitly specify one.

Perhaps you didn't *intend* to specify the last day of the year, in which 
case you ought to just accept that your writing wasn't as clear as you 
intended, instead of blaming others for failing to read your mind.



> Therefore, "the last day of the year" (in relativistic terms) is
> 11:59:59PM on the calendar day which _precedes_ the day of the month for
> which you were born.

Relativistic terms? You mean when travelling at 90% of the speed of light 
or in close orbit around a neutron star?

There are those language skills letting you down again :-P 

I think you mean *relative* terms.


[...]
>> Under your scheme, 99.7% of records will return the wrong age (off by
>> one) at least once per year. Statistically, 50% of queries will be
>> wrong.
> 
> 
> Can you whip-up a small code example which proves your assertion? Hey,
> and feel free to include the seven dwarfs if you like. ;-)

Under the racehorse scheme, 1/365 of your data will be born on the 1st of 
Jan, 1/365 on the 2nd Jan, and so on through 31st Dec. (Ignoring leap 
years.) Half of the data records will be updated early, and half will be 
updated late. Only those born on New Years Day (about 0.3% of the 
records) will be updated on the correct day. Hence 99.7% will be wrong 
for at least one day per year. If queries are made randomly, they'll be 
off by one 50% of the time.

Why 50%? 1/365 of your records will never be wrong, 1/365 will be wrong 
one day of the year, 1/365 will be wrong two days of the year, 1/365 will 
be wrong three days of the year, ... 1/365 will be wrong 364 days of the 
year. So on average, records are wrong 182 days of the year, which is 
close enough to half of 365. So if you query a random record on a random 
day, there's close enough to a fifty percent chance it will be off by one.

Now that I understand that you didn't intend this racehorse scheme, I'm 
not going to bother writing a simulation. But it is just simple 
statistics, assuming that the actual birthday is distributed randomly 
across the year, and assuming that queries for records come in at random 
times.

(And to be pedantic, I mean a uniform random distribution, and that 
queries and birthdays are independent.)



-- 
Steve

-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Are the critiques in "All the things I hate about Python" valid?

2018-02-26 Thread Rick Johnson
On Tuesday, February 20, 2018 at 5:45:36 PM UTC-6, Steven D'Aprano wrote:
> On Tue, 20 Feb 2018 12:42:23 -0800, Rick Johnson wrote:
>
> > For instance, if the age is queried many times a second,
> > it would be a much wiser design to set-up an event that
> > will advance the age at the end of the last second of
> > every year
>
> Do you really mean to say that everybody in the world has
> their birthday on January 1st? We're not racehorses you
> know.


No, silly rabbit. I was thinking about the problem from a
_relative_ perspective, whereas you were thinking about the
problem from a _global_ perspective. Neither perspective is
wrong.

If you read my exact words again:

"a much wiser design to set-up an event that will advance
the age at the end of the last second of every year"

...you'll notice that i mentioned no specific date.

Therefore, "the last day of the year" (in relativistic
terms) is 11:59:59PM on the calendar day which _precedes_
the day of the month for which you were born.

So, for instance: if your birthday is January 25th 1969, the
last second of the last day of your _first_ year is January
24th 1970 @ 11:59:59PM. And the last second of the last day
of your _second_ year is January 24th 1971 @ 11:59:59PM. And
so forth...

Does this make sense?


>
> Under your scheme, 99.7% of records will return the wrong
> age (off by one) at least once per year. Statistically, 50%
> of queries will be wrong.


Can you whip-up a small code example which proves your
assertion? Hey, and feel free to include the seven dwarfs if
you like. ;-)

-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Are the critiques in "All the things I hate about Python" valid?

2018-02-21 Thread Ian Kelly
On Tue, Feb 20, 2018 at 10:09 PM, Chris Angelico  wrote:
> On Wed, Feb 21, 2018 at 6:39 AM, Geldenhuys, J, Prof 
>  wrote:
>> I think your case illustrates the Python/Mathematica issue well:  you found 
>> a job for which Mathematica was not the perfect tool and you used Python.  
>> At the end of the day, both M & P have their place.  For example, we 
>> probably won't use either to teach Introduction Computer Science soon, 
>> because they both lack features that we expect our students to be familiar 
>> with at the end of their first year.
>>
>
> Out of curiosity, what features does Python lack in that area? (I
> don't know anything about Mathematica, and it's only tangentially
> on-topic at best.) For an intro to comp sci, I would generally expect
> to start with a high level language such as Python, or JavaScript
> (because of its ubiquity, primarily due to web browser usage), or Ruby
> (particularly if you're Japanese). You don't learn about how to manage
> memory (because it's done for you), but on the other hand, you don't
> learn about how to manage memory (because hey, it's all done for
> you!). You don't learn how to wade through a crash dump (because you
> have exceptions and tracebacks), you don't learn how to compile for
> different platforms, you don't learn all sorts of other things that
> aren't necessary for someone's first year in comp sci. So I'm
> interested to what such high level languages lack, from the POV of a
> first year of comp sci.

Indeed, MIT famously switched from Scheme to Python for their
introductory class about a decade back, and as far as I'm aware
they're still using it.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Are the critiques in "All the things I hate about Python" valid?

2018-02-21 Thread Michael F. Stemper

On 2018-02-18 22:55, Paul Rubin wrote:

Steven D'Aprano  writes:

"positive odd integers greater than 10 but less than 15003 divisible by
17 except for 850, 867 and 1394; or primes that aren't Mersenne
primes"

It *could* be a type, if your type system was sufficiently flexible to
allow you to specify something in that level of detail. Of course no
existing type system is.


Of course dependent types could do that (they have a type for every
proposition in constructive predicate calculus).  You might also be able
to do it with Liquid Haskell's refinement types, though automatically
checking them might not be so easy.


That's an easy one: even Pascal in the 1970s could deal with enumerated
types like the values 1, 3, 5, 7, 9. (I think.)


Idunno about Pascal, but Ada has integer range types.


Back in the early 1980s, I took a few courses involving Pascal,
and it certainly supported subranges then. Quoting from my
text[1]:

  A _scalar subrange_ data type is a data type composed of
  a specified range of any of the other standard or user-
  defined scalar types, except type REAL.

  We define a subrange type with a TYPE declaration of the
  following format.

TYPE type-name = lowerlimit..upperlimit;

  [...]

  Examples of subrange declarations are:

TYPE EXAMSCORES = 0..100;

Of course, Pascal being Pascal, a function to return the sum
of an array of INTEGER would refuse to return the sum of an
array of EXAMSCORES.[2]


[1] _An Introduction to Programming and Problem Solving With
Pascal_; Schneider, Weingart, and Perlman; (C) 1978
[2] Kernighan examines a similar issue in Section 2.1 of
"Why Pascal is Not My Favorite Programming Language",


Re: Are the critiques in "All the things I hate about Python" valid?

2018-02-21 Thread Michael F. Stemper

On 2018-02-18 22:55, Paul Rubin wrote:

Steven D'Aprano  writes:

"positive odd integers greater than 10 but less than 15003 divisible by
17 except for 850, 867 and 1394; or primes that aren't Mersenne
primes"

It *could* be a type, if your type system was sufficiently flexible to
allow you to specify something in that level of detail. Of course no
existing type system is.


Of course dependent types could do that (they have a type for every
proposition in constructive predicate calculus).  You might also be able
to do it with Liquid Haskell's refinement types, though automatically
checking them might not be so easy.


That's an easy one: even Pascal in the 1970s could deal with enumerated
types like the values 1, 3, 5, 7, 9. (I think.)


Idunno about Pascal, but Ada has integer range types.


Back in the early 1980s, I took a few courses involving Pascal,
and it certainly supported subranges then. Quoting from my
text[1]:

  A _scalar subrange_ data type is a data type composed of
  a specified range of any of the other standard or user-
  defined scalar types, except type REAL.

  We define a subrange type with a TYPE declaration of the
  following format.

TYPE type-name = lowerlimit..upperlimit;

  [...]

  Examples of subrange declarations are:

TYPE EXAMSCORES = 0..100;

Of course, Pascal being Pascal, a function to return the sum
of an array of INTEGER would refuse to return the sum of an
array of EXAMSCORES.[2]


[1] _An Introduction to Programming and Problem Solving With
Pascal_; Schneider, Weingart, and Perlman; (C) 1978
[2] Kernighan examines a similar issue in Section 2.1 of
"Why Pascal is Not My Favorite Programming Language",


--
Michael F. Stemper
You can lead a horse to water, but you can't make him talk like Mr. Ed
by rubbing peanut butter on his gums.
--
https://mail.python.org/mailman/listinfo/python-list


Re: Are the critiques in "All the things I hate about Python" valid?

2018-02-21 Thread Richard Damon

On 2/20/18 3:51 PM, Chris Angelico wrote:

On Wed, Feb 21, 2018 at 7:42 AM, Rick Johnson
 wrote:

On Tuesday, February 20, 2018 at 2:18:31 PM UTC-6, MRAB wrote:


The point he was making is that if you store a person's age, you'd have
to update it every year. It's far better to store the date of birth and
calculate the age on demand.

*AHEM*

At the risk of being labeled a "quibbler" (which, in the
grander scheme is not really all that bad considering some
of the names that have been attributed to me), i must say
your advice is only "sound advice" in cases where the age
will not be queried frequently.

For instance, if the age is queried many times a second, it
would be a much wiser design to set-up an event that will
advance the age at the end of the last second of every year,
instead of doing the age calculation many times a second.
Heck, even if the frequency is multiple time a day, a valid
argument could be made.

Nope. Even if you need the age many times per second, it's still
better to store the date of birth, because you eliminate boundary
conditions and duplicated data. But that's assuming you're storing the
age of *a person*. If the age in question is a boundary ("motor
insurance premiums are increased if the driver is 65 years or older"),
then it's still sane to store the age.

ChrisA


I would normally expect that the persistent store would have a birth 
date of the person, but within a local operation, you likely want to be 
able to assume the consistency of a attribute like over 55 years old, so 
you would compute the age, for that operation, but not keep it beyond 
that. Otherwise, depending on the order of doing your checks you may 
find that during your processing they are either both or neither of 
under 55 and over 55. It is much easier to reason that your code is 
correct when you can prevent (and thus ignore) such data races. This 
normally means your operation grabs the value of 'now' once, and all 
processing will be based on THAT point of time, not what currently is 
'now'. How big this 'timestop' needs to be depends on how wide the 
requirement is for temporal consistency. It might be just within a 
function, it might be for the full duration of the program run, 'now' 
might even be a parameter to the program, i.e. as of last (or next) 
midnight, do the computation.


--
Richard Damon

--
https://mail.python.org/mailman/listinfo/python-list


Re: Are the critiques in "All the things I hate about Python" valid?

2018-02-21 Thread Antoon Pardon
On 21-02-18 11:31, Terry Reedy wrote:
> On 2/21/2018 3:15 AM, Antoon Pardon wrote:
>> On 21-02-18 06:18, Terry Reedy wrote:
>>> On 2/20/2018 8:38 AM, Antoon Pardon wrote:
>>>
 People praise the dynamic nature of Python here on this list and then
 often enough seem to recoil when they see a piece of code really using
 that dynamism.
>>>
>>> ...
>>>
>>> When makes people recoil is abusing dynamism by needlessly rebinding a
>>> name to objects of different specific type within a single block of
>>> code.
>>>
>> But that was what Steven was complaining about. The fact that in a
>> static language
>> He would need two names if he wanted a variable in a single block of
>> code to be
>> first a number and then a string. At least that is how I understood him.
>
> I am not a party to any dispute between you and Steven.

But that was still the context in which the above contributions were made.

>
> I intentionally inserted 'needlessly' in that comment to cover the
> situation where a competent Python programmer has at least a plausible
> reason for rebinding within a block.  But in Python, this is rare
> compared to the constant binding of parameters names to whatever
> argument one passes.

I find 'needlessly' is without real meaning here. What one person finds needless
an other finds interesting. What one finds annoying insertions to placate the
type system, an other finds an interesting way to make intentions clear and
an implicite way to let the runtime check boundareis when needed.

The designer of Python have made their choice, fine I can live with their choice
and a lot of people even seem happy with that choice. That is fine too. It 
doesn't
mean we need to react as if all can be said about the alternatives is how 
annoying
they are.

>
> Types indicate how to treat a particular object or, in some computer
> languages, a block of memory.  Declaring a type for a name that is
> permanently attached to an information entity is an indirect way of
> associating a type with the entity.  If entities are tagged with their
> type, then names need not be.
>
That they don't need to be, doesn't contradict it could be usefull. If I have 
the
intention that a certain name will only ever be bound to numeric values between 
-10
and +10. Then IMO it would be usefull if one could express this in the language 
and
let the language runtime do the needed checks each time this name is rebound.

It certainly would be less annoying than repeatedly having to insert the same 
extra
code that checks for these restraints.

-- 
Antoon.


-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Are the critiques in "All the things I hate about Python" valid?

2018-02-21 Thread lorenzo . gatti
On Saturday, February 17, 2018 at 12:28:29 PM UTC+1, Ben Bacarisse wrote:
> Marko Rauhamaa  writes:
> 
> > Many people think static typing is key to high quality. I tend to think
> > the reverse is true: the boilerplate of static typing hampers
> > expressivity so much that, on the net, quality suffers.
> 
> I don't find that with Haskell.  It's statically typed but the types are
> almost always inferred.  If you see an explicit type, it's usually
> because the author thinks it helps explain something.
> 
> (I don't want to start a Haskell/Python thread -- the only point is that
> static typing does not inevitably imply lots of 'boilerplate'.)
> 
> -- 
> Ben.
There are two sides to not declaring types: having readers spend a fraction of 
a second to figure out what types are being used and having tools apply type 
inference for useful purposes. 
Python is bad at type inference (but only because deliberate loopholes like 
eval() are preserved) but good at making programmers trust code, while Haskell 
is bad at encouraging straightforward and understandable types but good at 
extracting maximum value from type inference.  
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Are the critiques in "All the things I hate about Python" valid?

2018-02-21 Thread Terry Reedy

On 2/21/2018 3:15 AM, Antoon Pardon wrote:

On 21-02-18 06:18, Terry Reedy wrote:

On 2/20/2018 8:38 AM, Antoon Pardon wrote:


People praise the dynamic nature of Python here on this list and then
often enough seem to recoil when they see a piece of code really using
that dynamism.


...

When makes people recoil is abusing dynamism by needlessly rebinding a
name to objects of different specific type within a single block of code.


But that was what Steven was complaining about. The fact that in a static 
language
He would need two names if he wanted a variable in a single block of code to be
first a number and then a string. At least that is how I understood him.


I am not a party to any dispute between you and Steven.

I intentionally inserted 'needlessly' in that comment to cover the 
situation where a competent Python programmer has at least a plausible 
reason for rebinding within a block.  But in Python, this is rare 
compared to the constant binding of parameters names to whatever 
argument one passes.


Types indicate how to treat a particular object or, in some computer 
languages, a block of memory.  Declaring a type for a name that is 
permanently attached to an information entity is an indirect way of 
associating a type with the entity.  If entities are tagged with their 
type, then names need not be.


--
Terry Jan Reedy

--
https://mail.python.org/mailman/listinfo/python-list


Re: Are the critiques in "All the things I hate about Python" valid?

2018-02-21 Thread Antoon Pardon
On 21-02-18 06:18, Terry Reedy wrote:
> On 2/20/2018 8:38 AM, Antoon Pardon wrote:
>
>> People praise the dynamic nature of Python here on this list and then
>> often enough seem to recoil when they see a piece of code really using
>> that dynamism.
>
> ...
>
> When makes people recoil is abusing dynamism by needlessly rebinding a
> name to objects of different specific type within a single block of code.
>
But that was what Steven was complaining about. The fact that in a static 
language
He would need two names if he wanted a variable in a single block of code to be
first a number and then a string. At least that is how I understood him.

-- 
Antoon.

-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Are the critiques in "All the things I hate about Python" valid?

2018-02-21 Thread Antoon Pardon
On 21-02-18 05:13, Steven D'Aprano wrote:
> On Tue, 20 Feb 2018 10:17:12 -0700, Ian Kelly wrote:
>
>> On Tue, Feb 20, 2018 at 8:38 AM, Steven D'Aprano
>>  wrote:
>>> On Tue, 20 Feb 2018 15:23:44 +0100, Antoon Pardon wrote:
>>>
> Okay. Now create a constraint on a name in C++ such that it can only
> accept integers representing A.D. years which, on the Gregorian
> calendar, are leap years. (Using a dedicated integer-like type is
> permitted.) It must accept all multiples of four, except those which
> are multiples of one hundred, unless they're also multiples of four
> hundred.
>
> That's what Steve asked for. Can you do it? Or is the C++ type system
> not flexible enough for that?
 Steve had multiple contributions in this thread. I didn't react to the
 one where he asked for that.
>>> Yes you did: you refused to meet the challenge, stating (and I quote):
>>>
>>> "Why should this be done at compile time?"
>>>
>>> https://mail.python.org/pipermail/python-list/2018-February/730995.html
>> I really don't understand what point you're driving at here, Steven.
> To be perfectly frank, neither do I any more. I fear I've been suckered 
> into taking a position I didn't intend to, as often happens when I reply 
> to Antoon Pardon.
>
> Obviously both statically and dynamically typed languages are Turing 
> Complete, so any constraint you can apply at run-time in one you can 
> apply at run-time in the other. How *easy* that is depends on the 
> language features, and particularly for older languages, statically typed 
> languages tend to be harder and less convenient to write in. There's 
> typically more boilerplate, and more time spent placating the type-
> checker. Do I need to justify this or can we take it as a given?
>
> So I didn't think I was taking a controversial position to say that 
> dynamic languages are good for writing constraints that are enforced at 
> run-time, *as opposed to trying to do so within the type-system* which 
> was the topic under discussion.

Yes it is controversial. You seem to conflate "within the type-system"
with "at compile time". If you want to make a general statement of
dynamically typed languages vs statically typed languages, I don't think
you can do that. There are plenty of statically typed languages that
also do run time checks.

I didn't sucker you into a position. Your inaccurate wording suckered you
into a position.

-- 
Antoon.

-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Are the critiques in "All the things I hate about Python" valid?

2018-02-21 Thread Antoon Pardon
On 20-02-18 16:38, Steven D'Aprano wrote:
> On Tue, 20 Feb 2018 15:23:44 +0100, Antoon Pardon wrote:
>
>>> Okay. Now create a constraint on a name in C++ such that it can only
>>> accept integers representing A.D. years which, on the Gregorian
>>> calendar, are leap years. (Using a dedicated integer-like type is
>>> permitted.) It must accept all multiples of four, except those which
>>> are multiples of one hundred, unless they're also multiples of four
>>> hundred.
>>>
>>> That's what Steve asked for. Can you do it? Or is the C++ type system
>>> not flexible enough for that?
>> Steve had multiple contributions in this thread. I didn't react to the
>> one where he asked for that.
> Yes you did: you refused to meet the challenge, stating (and I quote):

Look, you stated at a certain point that dynamic languages really excelled
at run time checks. That suggests that static languages don't. So when I
point out that static languages are just as good at run time checks, you
refer about how you want static languages to do their checks at compile time.

But the fact that you want static languages to do those things a compile
time, is not a good reason to claim that dynamic languages really excell
at run time checks, when in fact static languages are just as good at
doing run time checks.

-- 
Antoon Pardon.

-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Are the critiques in "All the things I hate about Python" valid?

2018-02-20 Thread Terry Reedy

On 2/20/2018 8:38 AM, Antoon Pardon wrote:


People praise the dynamic nature of Python here on this list and then
often enough seem to recoil when they see a piece of code really using
that dynamism.


Dynamic typing is the addition of run-time type information (RTTI) to 
data values.  This allows duck typing of function parameters and 
function code.  Every function that uses duck typing, which is to say, 
most functions written in Python, is 'really using that dynamism' as 
intended.  The concrete type of arguments may change with every call, 
but the function code uses run-time type dispatch to get type-specific 
versions of the operations needed.


For instance, builtin min has a single parameter whose abstract argument 
type is "iterable of '<'-compatible objects".  It's code somewhere 
compares current_min < next_item, which dispatches to current_min.__lt__ 
or possibly next_item.__ge__.  Combining "list of | tuple of | set of | 
frozenset of | iterable of | dict keyed with" witn "ints | doubles | 
strings | bytes | '<'-compatible lists | '<'-compatible tuples" gives 36 
possible concrete input types.  "array of x" gives an indefinite number 
more, as does user additions.  I really like that we do not have to 
define a 'min_collection_type' function for every combination we might 
want to use in a package.


When makes people recoil is abusing dynamism by needlessly rebinding a 
name to objects of different specific type within a single block of code.


--
Terry Jan Reedy

--
https://mail.python.org/mailman/listinfo/python-list


Re: Are the critiques in "All the things I hate about Python" valid?

2018-02-20 Thread Chris Angelico
On Wed, Feb 21, 2018 at 6:39 AM, Geldenhuys, J, Prof 
 wrote:
> I think your case illustrates the Python/Mathematica issue well:  you found a 
> job for which Mathematica was not the perfect tool and you used Python.  At 
> the end of the day, both M & P have their place.  For example, we probably 
> won't use either to teach Introduction Computer Science soon, because they 
> both lack features that we expect our students to be familiar with at the end 
> of their first year.
>

Out of curiosity, what features does Python lack in that area? (I
don't know anything about Mathematica, and it's only tangentially
on-topic at best.) For an intro to comp sci, I would generally expect
to start with a high level language such as Python, or JavaScript
(because of its ubiquity, primarily due to web browser usage), or Ruby
(particularly if you're Japanese). You don't learn about how to manage
memory (because it's done for you), but on the other hand, you don't
learn about how to manage memory (because hey, it's all done for
you!). You don't learn how to wade through a crash dump (because you
have exceptions and tracebacks), you don't learn how to compile for
different platforms, you don't learn all sorts of other things that
aren't necessary for someone's first year in comp sci. So I'm
interested to what such high level languages lack, from the POV of a
first year of comp sci.

ChrisA
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Are the critiques in "All the things I hate about Python" valid?

2018-02-20 Thread Geldenhuys, J, Prof <g...@sun.ac.za>
Hi Marcel,

I have read through the article and it seems to me that all of the problems 
described boil down to one important point: use the right tool for the right 
job.  Python is probably not the best language for developing large, complex 
systems (although there are such systems).  Most (or all?) of the concerns that 
Murthy raises (dynamic typing, support for multithreading, performance, 
Python2/3, encapsulation) speak to that.  He is not wrong about any of the 
points, but it could be said that he is expecting too much.  We don't expect a 
carpenter with a hammer to build an entire apartment building, and we don't 
expect a big construction company to build a coffee table.

Python does have many desirable features: it is easy to learn and the code is 
relatively clear.  It is available on most platforms (I can run it directly on 
my phone), and it is easy to port to new platforms.  There are many things that 
Mathematica can do that Python can't, and vice versa.  Right tool/right job.  I 
have often used Python to build prototypes to see if an algorithm works, but 
then I use a more efficient language (like Java or C) for the "real" 
implementation.

Out of interest, Mathematica itself is written in C, C++, and Java, and 
consists of a few million lines of code.  Python has several implementations; 
the "reference" implementation is CPython which is written in C and consists of 
 ~540,000 lines of code.  Because Python is open-source, it has the strengths 
(many contributors) and weaknesses (more difficult to coordinate development) 
that comes from this paradigm.

As far as the documentation is concerned, Python is considered a 
well-documented language.  Of course, individual libraries may not be, but as 
it happens, pyeda has good documentation 
(http://pyeda.readthedocs.io/en/latest/).  I think you may just have been 
unlucky not to have found it.

I think your case illustrates the Python/Mathematica issue well:  you found a 
job for which Mathematica was not the perfect tool and you used Python.  At the 
end of the day, both M & P have their place.  For example, we probably won't 
use either to teach Introduction Computer Science soon, because they both lack 
features that we expect our students to be familiar with at the end of their 
first year.



Prof Jaco Geldenhuys
Medeprofessor: Rekenaarwetenskap  |  Associate Professor: Computer Science
Fakulteit Natuurwetenskappe  |  Faculty of Science
e: g...@sun.ac.za  |  t: +27 21 808 4232  |  a: Algemene Ingenieurswese Gebou 
A519  |  General Engineering Building A519
  
 
 

 
 


On 2018/02/20, 19:11, "Wild, Marcel, Prof "  
wrote:

I scarcely know Python, and I have no intention delving into it further.
 I was forced to use Python because it features binary decision diagrams, 
which MATHEMATICA doesn't. Coming from Mathematica the account of Nathan Murphy 
reads like a nightmare.

The one point that stroke me the most was the schism between Python 2 and 
3. No such thing with Mathematica: All its 11 or more versions are fully 
compatible, I never experienced any problems in this regard.

Another point is the bad online help provided to "teach yourself" Python. 
For instance, it took me more than an hour to find out how to negate a Boolean 
variable, whereas in Mathematica you would just type "Negation" in the Wolfram 
Documentation search window, and get the information you need.

I know one pays for Mathematica whereas Python is open source, but I've 
come to realize now that this money is very well spent!

Question: Apart from a few commands not available in Mathematica, such as 
expr2bdd, is there really any domain of computation where Mathematica is 
inferior to Python?

Marcel

-Original Message-
From: Python-list [mailto:python-list-bounces+mwild=sun.ac...@python.org] 
On Behalf Of bartc
Sent: 19 February 2018 02:35 PM
To: python-list@python.org
Subject: Re: Are the critiques in "All the things I hate about Python" 
valid?

On 19/02/2018 02:59, Chris Angelico wrote:
> On Mon, Feb 19, 2018 at 1:14 PM, bartc  wrote:

>> How would even a type for the odd numbers from 1 to 10 inclusive work?
>> (That, a type consisting of one of the values in {1,3,5,7,9}.) Would
>> they be ordered or unordered? Can I do arithmetic with them: will 3*3
>> work, but not 3*5?
>
> The type is "positive odd number below ten" and could be written as
> int(1..9|1%2). That is an orderable type; you can say that 3 < 7, for
> instance. And yes, arithmetic would be defined just fine;


Re: Are the critiques in "All the things I hate about Python" valid?

2018-02-20 Thread Chris Angelico
On Wed, Feb 21, 2018 at 9:01 AM, Rick Johnson
 wrote:
> On Tuesday, February 20, 2018 at 2:51:56 PM UTC-6, Chris Angelico wrote:
> [...]
>> Nope. Even if you need the age many times per second, it's still
>> better to store the date of birth, because you eliminate boundary
>> conditions and duplicated data.
>
> You failed to provide any examples proving this assertion of
> yours. I can't imagine how either would be a problem.

https://en.wikipedia.org/wiki/Database_normalization

I'm not going to do your research for you.

ChrisA
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Are the critiques in "All the things I hate about Python" valid?

2018-02-20 Thread Steven D'Aprano
On Tue, 20 Feb 2018 10:17:12 -0700, Ian Kelly wrote:

> On Tue, Feb 20, 2018 at 8:38 AM, Steven D'Aprano
>  wrote:
>> On Tue, 20 Feb 2018 15:23:44 +0100, Antoon Pardon wrote:
>>
 Okay. Now create a constraint on a name in C++ such that it can only
 accept integers representing A.D. years which, on the Gregorian
 calendar, are leap years. (Using a dedicated integer-like type is
 permitted.) It must accept all multiples of four, except those which
 are multiples of one hundred, unless they're also multiples of four
 hundred.

 That's what Steve asked for. Can you do it? Or is the C++ type system
 not flexible enough for that?
>>>
>>> Steve had multiple contributions in this thread. I didn't react to the
>>> one where he asked for that.
>>
>> Yes you did: you refused to meet the challenge, stating (and I quote):
>>
>> "Why should this be done at compile time?"
>>
>> https://mail.python.org/pipermail/python-list/2018-February/730995.html
> 
> I really don't understand what point you're driving at here, Steven.

To be perfectly frank, neither do I any more. I fear I've been suckered 
into taking a position I didn't intend to, as often happens when I reply 
to Antoon Pardon.

Obviously both statically and dynamically typed languages are Turing 
Complete, so any constraint you can apply at run-time in one you can 
apply at run-time in the other. How *easy* that is depends on the 
language features, and particularly for older languages, statically typed 
languages tend to be harder and less convenient to write in. There's 
typically more boilerplate, and more time spent placating the type-
checker. Do I need to justify this or can we take it as a given?

So I didn't think I was taking a controversial position to say that 
dynamic languages are good for writing constraints that are enforced at 
run-time, *as opposed to trying to do so within the type-system* which 
was the topic under discussion.

I have argued in the past that the hard distinction between static and 
dynamic languages has been gradually worn away (if it ever existed at 
all!) as statically-typed languages add dynamic features, and dynamically-
typed languages add static features. For example, Java supports run-time 
method dispatch; Python added type annotations to standardise on syntax 
for static type testing.

Antoon's example of Pascal range checking is another run-time feature (a 
form of dynamic typing, in a fifty year old statically typed language no 
less!), as are Eiffel pre- and post-condition assertions (although the 
compiler can optimize them away if it can determine that they always 
hold). I've linked to Steve Yegge a lot,  e.g.:

https://
steve-yegge.blogspot.com.au/2008/05/dynamic-languages-strike-back.html

so I certainly know that there's a certain amount of convergence between 
static and dynamic features and it was never my intention to suggest that 
statically-typed code can't validate values at run-time. That would be a 
ludicrous position to take.

If Antoon was arguing in good faith surely he must have realised I 
couldn't have meant that. By all means call me out on factual 
inaccuracies, but do so in good faith. Don't assume I mean something 
ludicrous.


If you look back at my reply to Bart:

https://mail.python.org/pipermail/python-list/2018-February/730943.html

you will see that the context is a discussion comparing:

compile-time static analysis 

versus 

run-time dynamic checks

strategies. Hence my challenge to perform the same kind of check at 
compile-time using an actual, existing type-system. (Not merely say a 
sufficiently clever type-system can do it and handwave away the practical 
difficulties.)

Of course we can perform arbitrarily complex run-time checks in a 
language with static typing (it might not be as convenient or easy, 
especially if you have to declare every single temporary variable, do a 
lot of explicit casts, never re-use any variable, and use a lot of 
verbose boilerplate, but it can be done).


> The
> original claim (by you) was that dynamic languages excel at "enforcing
> constraints at run-time which are hard to enforce at compile-time". The
> counter-argument, as I understand, it was that while the constraints may
> be hard to enforce at compile-time, they are just as easy to enforce at
> run-time in a static language as in a dynamic language, so that can't
> really be considered a *strength* per se of dynamic languages.

Fair enough -- I acknowledge there's something to what you say, even if I 
wouldn't say it that way.

But in which case, if dynamically typed languages are no easier to use 
than statically typed ones, and no faster, and no more secure, why do 
people use them?

The conventional answer is that they are easier to use, hence more rapid 
prototyping and application development. But if we say that static typed 
languages are *just as easy to use* then the existence and popularity of 

Re: Are the critiques in "All the things I hate about Python" valid?

2018-02-20 Thread Steven D'Aprano
On Tue, 20 Feb 2018 12:42:23 -0800, Rick Johnson wrote:

> For instance, if the age is queried many times a second, it would be a
> much wiser design to set-up an event that will advance the age at the
> end of the last second of every year

Do you really mean to say that everybody in the world has their birthday 
on January 1st? We're not racehorses you know.

Under your scheme, 99.7% of records will return the wrong age (off by 
one) at least once per year. Statistically, 50% of queries will be wrong.


-- 
Steve

-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Are the critiques in "All the things I hate about Python" valid?

2018-02-20 Thread Steven D'Aprano
On Tue, 20 Feb 2018 22:19:13 +0100, Christian Gollwitzer wrote:

[...]
> LeapYearCheck could be implemented using template metaprogramming
> (quite horrible) or the new funky constexpr feature in C++11/C++14 (less
> horrible).

Thanks Christian. That's certainly interesting, I don't know much about 
template metaprogramming so TIL.

 

-- 
Steve

-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Are the critiques in "All the things I hate about Python" valid?

2018-02-20 Thread Steven D'Aprano
On Tue, 20 Feb 2018 17:11:05 +, Wild, Marcel, Prof 
wrote:

> I scarcely know Python, and I have no intention delving into it further.
>  I was forced to use Python because it features binary decision
>  diagrams, which MATHEMATICA doesn't. Coming from Mathematica the
>  account of Nathan Murphy reads like a nightmare.

I dare say that was Nathan Murphy's intention. But the ironic thing is 
that by Murphy's standards, Mathematica suffers the same flaws as Python: 
it to is a dynamically typed language with little or no compile-time type 
safety.



-- 
Steve

-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Are the critiques in "All the things I hate about Python" valid?

2018-02-20 Thread Rick Johnson
On Tuesday, February 20, 2018 at 2:51:56 PM UTC-6, Chris Angelico wrote:
[...]
> Nope. Even if you need the age many times per second, it's still
> better to store the date of birth, because you eliminate boundary
> conditions and duplicated data.

You failed to provide any examples proving this assertion of
yours. I can't imagine how either would be a problem.

> But that's assuming you're storing the age of *a person*.
> If the age in question is a boundary ("motor insurance
> premiums are increased if the driver is 65 years or
> older"), then it's still sane to store the age.

The boundary problem you outline here is a simple matter of
checking the age annually and increasing the premium if the
person is 65 years or older, and has nothing to do with
whether or not the age is calculated once a year or upon
every request.

def annual_probe(self, geriatricMarker=65):
self.age += 1
if self.age >= geriatricMarker:
self.increase_premium()

But obviously this "data" should reside in a database, not be
instanced into OO objects.

-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Are the critiques in "All the things I hate about Python" valid?

2018-02-20 Thread Christian Gollwitzer

Am 20.02.18 um 14:58 schrieb Chris Angelico:

Okay. Now create a constraint on a name in C++ such that it can only
accept integers representing A.D. years which, on the Gregorian
calendar, are leap years. (Using a dedicated integer-like type is
permitted.) It must accept all multiples of four, except those which
are multiples of one hundred, unless they're also multiples of four
hundred.

That's what Steve asked for. Can you do it? Or is the C++ type system
not flexible enough for that?


It might be possible to do that with compile-time checking for 
compile-time constants. For runtime checking, you already got the answer 
- provide a


class LeapYear {
LeapYear(int y) {
if (!condition) throw std::runtime_eror();
}
operator = (int y) { ...also test and throw... }
};

then:

LeapYear y2000 = 2000; // works
y2000 = 2004; // works
y2000 = 2001; // throws an error

The difference to Python is that "a=b" and "a+=b" are similar in C++, in 
both cases you call a method on the object "a", whereas in Python the 
first one is handled independently of the type of "a".


If you insist in compile-time checking, I think it's possible, though 
I'm not one of those C++ wizards to implement it from up my sleeve. The 
basic technique will be that you make your LeapYear 
constructible/assignable from a static type only where constructino of 
the type fails if the condition is not met. So


class LeapYear {
...
template operator = (LeapYearCheck y)
{
// at this point, we are sure that LeapYearCheck succeeded
}
};

LeapYearCheck could be implemented using template metaprogramming 
(quite horrible) or the new funky constexpr feature in C++11/C++14 (less 
horrible).


However this will throw an error whenever the compiler can't prove that 
the year is a leap year, effectively only when it can be computed at 
compile time, which certainly limits the usefulness of this type.

--
https://mail.python.org/mailman/listinfo/python-list


Re: Are the critiques in "All the things I hate about Python" valid?

2018-02-20 Thread Chris Angelico
On Wed, Feb 21, 2018 at 7:42 AM, Rick Johnson
 wrote:
> On Tuesday, February 20, 2018 at 2:18:31 PM UTC-6, MRAB wrote:
>
>> The point he was making is that if you store a person's age, you'd have
>> to update it every year. It's far better to store the date of birth and
>> calculate the age on demand.
>
> *AHEM*
>
> At the risk of being labeled a "quibbler" (which, in the
> grander scheme is not really all that bad considering some
> of the names that have been attributed to me), i must say
> your advice is only "sound advice" in cases where the age
> will not be queried frequently.
>
> For instance, if the age is queried many times a second, it
> would be a much wiser design to set-up an event that will
> advance the age at the end of the last second of every year,
> instead of doing the age calculation many times a second.
> Heck, even if the frequency is multiple time a day, a valid
> argument could be made.

Nope. Even if you need the age many times per second, it's still
better to store the date of birth, because you eliminate boundary
conditions and duplicated data. But that's assuming you're storing the
age of *a person*. If the age in question is a boundary ("motor
insurance premiums are increased if the driver is 65 years or older"),
then it's still sane to store the age.

ChrisA
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Are the critiques in "All the things I hate about Python" valid?

2018-02-20 Thread bartc

On 20/02/2018 20:17, MRAB wrote:

On 2018-02-20 19:17, bartc wrote:

On 20/02/2018 19:04, Dennis Lee Bieber wrote:
On Tue, 20 Feb 2018 17:11:05 +, "Wild, Marcel, Prof 
"

 declaimed the following:



So the special type of the values 65..90 might not allow the type be 
multiplied or divided, or added to itself. Because they represent 
characters A..Z. Or house numbers. Or the age of pensioners. (You'd 
need to convert to ordinary integers, is that is allowed.)



Off-hand -- if you are storing the /age of pensioners/, you have an
inappropriate data model... Age being a time varying value computed as:
    time_now - date_of_birth
and date_of_birth is the proper entity for storage...


If you wanted a scientifically exact value, maybe.

But someone who's 24.157094 years old now won't say their age is
24.157094 (and 24.157104 five minutes later). They will usually say they
are 24, until they are 25 (much older people prefer to round upwards,
for some reason).

So age is usually colloquially specified as an integer from 1 to around
100. Other than for young children where the lack of precision requires
the use of fractions or to switch to whole numbers of months or weeks.

The point he was making is that if you store a person's age, you'd have 
to update it every year. It's far better to store the date of birth and 
calculate the age on demand.


People are making too much of my example of a type consisting of a set 
of special values.


Anyway the values might not relate to an individual; they could be 
indices into a data structure so that C[65] gives you the number of 
65-year-olds or something, or 67 is the age at which someone is entitled 
to a pension.


--
bartc
--
https://mail.python.org/mailman/listinfo/python-list


Re: Are the critiques in "All the things I hate about Python" valid?

2018-02-20 Thread Rick Johnson
On Tuesday, February 20, 2018 at 2:18:31 PM UTC-6, MRAB wrote:

> The point he was making is that if you store a person's age, you'd have 
> to update it every year. It's far better to store the date of birth and 
> calculate the age on demand.

*AHEM*

At the risk of being labeled a "quibbler" (which, in the
grander scheme is not really all that bad considering some
of the names that have been attributed to me), i must say
your advice is only "sound advice" in cases where the age
will not be queried frequently.

For instance, if the age is queried many times a second, it
would be a much wiser design to set-up an event that will
advance the age at the end of the last second of every year,
instead of doing the age calculation many times a second.
Heck, even if the frequency is multiple time a day, a valid
argument could be made.

Of course. Outside of buggy loop that, much to the chagrin
of the code monkey who wrote it waxes infinite, i cannot
image many scenarios in which someone's age would be queried
many times a second.

But hey, this is Python-list after all. And i wouldn't be a
true pal i didn't point out an implicit corner case.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Are the critiques in "All the things I hate about Python" valid?

2018-02-20 Thread MRAB

On 2018-02-20 19:17, bartc wrote:

On 20/02/2018 19:04, Dennis Lee Bieber wrote:

On Tue, 20 Feb 2018 17:11:05 +, "Wild, Marcel, Prof "
 declaimed the following:



So the special type of the values 65..90 might not allow the type be multiplied 
or divided, or added to itself. Because they represent characters A..Z. Or 
house numbers. Or the age of pensioners. (You'd need to convert to ordinary 
integers, is that is allowed.)



Off-hand -- if you are storing the /age of pensioners/, you have an
inappropriate data model... Age being a time varying value computed as:
time_now - date_of_birth
and date_of_birth is the proper entity for storage...


If you wanted a scientifically exact value, maybe.

But someone who's 24.157094 years old now won't say their age is
24.157094 (and 24.157104 five minutes later). They will usually say they
are 24, until they are 25 (much older people prefer to round upwards,
for some reason).

So age is usually colloquially specified as an integer from 1 to around
100. Other than for young children where the lack of precision requires
the use of fractions or to switch to whole numbers of months or weeks.

The point he was making is that if you store a person's age, you'd have 
to update it every year. It's far better to store the date of birth and 
calculate the age on demand.

--
https://mail.python.org/mailman/listinfo/python-list


Re: Are the critiques in "All the things I hate about Python" valid? (Posting On Python-List Prohibited)

2018-02-20 Thread bartc

On 20/02/2018 19:35, Lawrence D’Oliveiro wrote:

On Wednesday, February 21, 2018 at 1:43:41 AM UTC+13, bartc wrote:

In Pascal (and presumably Ada) then all the
gubbins need to make this work properly:

var x: 1..10;

x = 10;
x = x + 1;   { error? }


Error on both statements. Pascal doesn’t allow a statement to just consist of 
an expression. At least, it didn’t the last time I checked.


OK, I forgot it needs := for assignment.


Besides, it’s not clear what the point is of doing a comparison between those 
terms and throwing the result away.


Many languages including Python allow exactly that.

(The ones I create make it an error. Only certain kinds of expression 
terms also have versions that can meaningfully be independent statements.)


--
bartc
--
https://mail.python.org/mailman/listinfo/python-list


Re: Are the critiques in "All the things I hate about Python" valid?

2018-02-20 Thread Grant Edwards
On 2018-02-20, Rhodri James  wrote:

> The schism is not as wide as you are implying.  Aside from "print" 
> becoming a function, which is blindingly obvious whenever you trip over 
> it, there is relatively little reason why an ordinary Pythonista would 
> care whether he or she was running Python 2 or Python 3.

Any ordinary Pythonista to deals with raw data "bytes" cares a great
deal.  There are major differences between the Py2 and Py3 in that
area, and they're a royal PITA to deal with.

-- 
Grant Edwards   grant.b.edwardsYow! Are you mentally here
  at   at Pizza Hut??
  gmail.com

-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Are the critiques in "All the things I hate about Python" valid?

2018-02-20 Thread bartc

On 20/02/2018 19:04, Dennis Lee Bieber wrote:

On Tue, 20 Feb 2018 17:11:05 +, "Wild, Marcel, Prof "
 declaimed the following:



So the special type of the values 65..90 might not allow the type be multiplied 
or divided, or added to itself. Because they represent characters A..Z. Or 
house numbers. Or the age of pensioners. (You'd need to convert to ordinary 
integers, is that is allowed.)



Off-hand -- if you are storing the /age of pensioners/, you have an
inappropriate data model... Age being a time varying value computed as:
time_now - date_of_birth
and date_of_birth is the proper entity for storage...


If you wanted a scientifically exact value, maybe.

But someone who's 24.157094 years old now won't say their age is 
24.157094 (and 24.157104 five minutes later). They will usually say they 
are 24, until they are 25 (much older people prefer to round upwards, 
for some reason).


So age is usually colloquially specified as an integer from 1 to around 
100. Other than for young children where the lack of precision requires 
the use of fractions or to switch to whole numbers of months or weeks.



--
bartc
--
https://mail.python.org/mailman/listinfo/python-list


Re: Are the critiques in "All the things I hate about Python" valid?

2018-02-20 Thread Ben Finney
"Wild, Marcel, Prof "  writes:

> I scarcely know Python, and I have no intention delving into it
> further.

That's fine. This is a forum for those who do have an ongoing interest
in Python. I think your needs would be better served elsewhere.

-- 
 \   “Prediction is very difficult, especially of the future.” |
  `\   —Niels Bohr |
_o__)  |
Ben Finney

-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Are the critiques in "All the things I hate about Python" valid?

2018-02-20 Thread Rhodri James

On 20/02/18 17:11, Wild, Marcel, Prof  wrote:

I scarcely know Python, and I have no intention delving into it further.
  I was forced to use Python because it features binary decision diagrams, 
which MATHEMATICA doesn't. Coming from Mathematica the account of Nathan Murphy 
reads like a nightmare.



I have to admit, I have no idea what you're talking about.  I suspect, 
though, that you would find a similar discussion of any other 
programming language at least as nightmarish.



The one point that stroke me the most was the schism between Python 2 and 3. No 
such thing with Mathematica: All its 11 or more versions are fully compatible, 
I never experienced any problems in this regard.


The schism is not as wide as you are implying.  Aside from "print" 
becoming a function, which is blindingly obvious whenever you trip over 
it, there is relatively little reason why an ordinary Pythonista would 
care whether he or she was running Python 2 or Python 3.  Python 3.5 vs 
Python 3.7 is much more likely to be a relevant question, because of 
course Python has evolved new features over time.


The statement "all its [...] versions are fully compatible" implies 
Mathematica hasn't evolved over those versions.  I sincerely doubt that 
is true.



Another point is the bad online help provided to "teach yourself" Python. For instance, 
it took me more than an hour to find out how to negate a Boolean variable, whereas in Mathematica 
you would just type "Negation" in the Wolfram Documentation search window, and get the 
information you need.


This is likely to be a personal thing.  Mathematica ties you firmly to 
its IDE; you get all the bells and whistles of that IDE, but only the 
bells and whistles of that IDE.  Python doesn't tie you to anything in 
particular, so you have to provide your own bells and whistles (but can 
provide any you can find or create).


That said, you are not making a good case for your research skills. 
Googling "python boolean negation" got me the information in under a 
minute, including the Firefox startup time.  Reading through the Boolean 
Expressions part of the online documentation at docs.python.com took 
little longer, though admittedly that isn't meant for beginners.  Even 
firing up a Python interpreter and typing


>>> help("not")

didn't take that long (and honestly, "negation" is not the first word I 
think of when inverting booleans).




I know one pays for Mathematica whereas Python is open source, but I've come to 
realize now that this money is very well spent!

Question: Apart from a few commands not available in Mathematica, such as 
expr2bdd, is there really any domain of computation where Mathematica is 
inferior to Python?


Not knowing much about Mathematica, all I can say is "almost certainly."

--
Rhodri James *-* Kynesim Ltd
--
https://mail.python.org/mailman/listinfo/python-list


Re: Are the critiques in "All the things I hate about Python" valid?

2018-02-20 Thread Richard Damon


> On Feb 20, 2018, at 8:58 AM, Chris Angelico  wrote:
> 
>> On Wed, Feb 21, 2018 at 12:53 AM, Antoon Pardon  wrote:
>> In C++ I can do something like:
>> 
>>  SomeClass MyVar;
>> 
>> And after that the kind of possible assignments to MyVar are constraint. It
>> makes the runtime throw an error when somewhere the program tries to assign
>> something to MyVar that isn't allowed by SomeClass.
>> 
>> You can't put such constraints on names in Python.
>> 
>> In C++ I can do some like:
>>Some_Class: MyVar;
>> 
>> And after that, It will be impossible to assign a value to MyVar that
>> doesn't meet the
>> constraints imposed by the constructor/copy operator. You have put
>> somekind of
>> contract on the name MyVar, that limits the kind of things assignable to
>> it. You
>> can't put such constraints on a name in Python.
> 
> Okay. Now create a constraint on a name in C++ such that it can only
> accept integers representing A.D. years which, on the Gregorian
> calendar, are leap years. (Using a dedicated integer-like type is
> permitted.) It must accept all multiples of four, except those which
> are multiples of one hundred, unless they're also multiples of four
> hundred.
> 
> That's what Steve asked for. Can you do it? Or is the C++ type system
> not flexible enough for that?
> 
> ChrisA
> -- 
> https://mail.python.org/mailman/listinfo/python-list

Such a class would be fairly trivial to write in C++, or I suspect Python.

In C++ you would have a constructor and possibilities an assignment operator 
that takes an integer, tests it for validity and throw/asserts if it is 
incorrect. (Depending on other requirements, you might allow or not implicit 
conversions)
It probably also has a constructor and an assignment operator that takes a 
‘LeapYear’ and just uses it.
To be usable, it will need something to allow you to get the integer value out, 
might be implicit or explicit.

The big issue with such a type, and why it doesn’t make much sense as a type, 
is that there is very little that can be done with such a type, as there is no 
interesting operation for which the type is at least mostly closed under, at 
best it is closed under +400*n
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Are the critiques in "All the things I hate about Python" valid?

2018-02-20 Thread Rick Johnson
On Tuesday, February 20, 2018 at 9:40:37 AM UTC-6, Steven D'Aprano wrote:
[...]
> Yes you did: you refused to meet the challenge, stating (and I quote):

I'm always entertained by Steven's so-called "challenges". You see, Steven is
addicted to winning, and he'll do anything to win a debate, even construct a
challenge that is obviously untenable. A typical example of Steven's
absurd challenges goes something like this:


from absurd.challenges.missonimpossible import Message

body = """
MISSON: MOVE YOURSELF FROM YOUR CURRENT POSITION ON THE
ON THIS EARTH TO THE TOP OF THE EIFFEL TOWER IN PARIS,
FRANCE.

CAVEAT_1: You cannot use public or private modes of
transportation. Including, (but not limited to): planes,
trains automobiles, boats, jet-skis, roller- skates,
skate boards, kites, gliders, bicycles, tricycles,
unicycles, big- wheels, hot-air balloons, magic carpets,
etc...

CAVEAT_2: Neither may you move yourself using your own
forms of bodily locomotion. Including (but not limited
to): crawling, walking, running, jogging, rolling,
skipping, jumping, hopping, cartwheels, backflips,
etc...

CAVEAT_3: Neither may you utilize the animal kingdom to
transport yourself. Including (but not limited to):
Being carried by an army of ants, a flock of birds, a
gang of gorilla, or a pod of orca, etc...

CAVEAT_4: If you happen to be at the top of the Eiffel
tower upon learning of this challenge, it doesn't count.
But please do post a pic on Instagram, as i rather enjoy
a good view. Thanks :-)

CAVEAT_5: Teleportation is strictly forbidden! Although
it'd be a neat trick. And if you have a working
prototype i'd love to stop by for a personal
demonstration and have a chance to make copies of the
schematics and the code base. (for documentation
purposes only, of course)

This is your misson, should you choose to accept it...
"""

if __name__ == '__main__':
msg = Message(title="Loco-motion", body=body)
msg.play_async("misson_impossible.mp3")
print msg
msg.after(10, exit)
raw_input('\nThis message will self destruct in ~10 seconds...')

-- 
https://mail.python.org/mailman/listinfo/python-list


RE: Are the critiques in "All the things I hate about Python" valid?

2018-02-20 Thread Wild, Marcel, Prof <mw...@sun.ac.za>
I scarcely know Python, and I have no intention delving into it further.
 I was forced to use Python because it features binary decision diagrams, which 
MATHEMATICA doesn't. Coming from Mathematica the account of Nathan Murphy reads 
like a nightmare.

The one point that stroke me the most was the schism between Python 2 and 3. No 
such thing with Mathematica: All its 11 or more versions are fully compatible, 
I never experienced any problems in this regard.

Another point is the bad online help provided to "teach yourself" Python. For 
instance, it took me more than an hour to find out how to negate a Boolean 
variable, whereas in Mathematica you would just type "Negation" in the Wolfram 
Documentation search window, and get the information you need.

I know one pays for Mathematica whereas Python is open source, but I've come to 
realize now that this money is very well spent!

Question: Apart from a few commands not available in Mathematica, such as 
expr2bdd, is there really any domain of computation where Mathematica is 
inferior to Python?

Marcel

-Original Message-
From: Python-list [mailto:python-list-bounces+mwild=sun.ac...@python.org] On 
Behalf Of bartc
Sent: 19 February 2018 02:35 PM
To: python-list@python.org
Subject: Re: Are the critiques in "All the things I hate about Python" valid?

On 19/02/2018 02:59, Chris Angelico wrote:
> On Mon, Feb 19, 2018 at 1:14 PM, bartc  wrote:

>> How would even a type for the odd numbers from 1 to 10 inclusive work?
>> (That, a type consisting of one of the values in {1,3,5,7,9}.) Would
>> they be ordered or unordered? Can I do arithmetic with them: will 3*3
>> work, but not 3*5?
>
> The type is "positive odd number below ten" and could be written as
> int(1..9|1%2). That is an orderable type; you can say that 3 < 7, for
> instance. And yes, arithmetic would be defined just fine;

Sometimes, the reason for creating a special numerical type is precisely so you 
can't do arithmetic on them, if it's not meaningful for the type.

So the special type of the values 65..90 might not allow the type be multiplied 
or divided, or added to itself. Because they represent characters A..Z. Or 
house numbers. Or the age of pensioners. (You'd need to convert to ordinary 
integers, is that is allowed.)

  there's no
> requirement for the result of an operation to have the same type as
> its inputs:

>
 5 / 2 # two integers
> 2.5

Try that when the type of {1..13} represents playing card ordinal values.

Type systems get rapidly very complicated when you have to deal with arbitrary 
sets of values and with arbitrary rules of interaction.
Someone has to devise a programming language to allow all that without tying 
itself up in knots. Someone else has to program in it. And someone else has to 
try and understand it!

Ones like C++ has already tied itself itself up in knots just doing the basics; 
I'm not sure how it would handle even my 1,3,5,7,9 type.

But Python has classes and can do some of this stuff; how would it handle a 
numeric type that is constrained to be whole numbers within
0..9 inclusive?

--
bartc
--
https://mail.python.org/mailman/listinfo/python-list
The integrity and confidentiality of this email is governed by these terms / 
Die integriteit en vertroulikheid van hierdie e-pos word deur die volgende 
bepalings gereël. http://www.sun.ac.za/emaildisclaimer
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Are the critiques in "All the things I hate about Python" valid?

2018-02-20 Thread Ian Kelly
On Tue, Feb 20, 2018 at 8:38 AM, Steven D'Aprano
 wrote:
> On Tue, 20 Feb 2018 15:23:44 +0100, Antoon Pardon wrote:
>
>>> Okay. Now create a constraint on a name in C++ such that it can only
>>> accept integers representing A.D. years which, on the Gregorian
>>> calendar, are leap years. (Using a dedicated integer-like type is
>>> permitted.) It must accept all multiples of four, except those which
>>> are multiples of one hundred, unless they're also multiples of four
>>> hundred.
>>>
>>> That's what Steve asked for. Can you do it? Or is the C++ type system
>>> not flexible enough for that?
>>
>> Steve had multiple contributions in this thread. I didn't react to the
>> one where he asked for that.
>
> Yes you did: you refused to meet the challenge, stating (and I quote):
>
> "Why should this be done at compile time?"
>
> https://mail.python.org/pipermail/python-list/2018-February/730995.html

I really don't understand what point you're driving at here, Steven.
The original claim (by you) was that dynamic languages excel at
"enforcing constraints at run-time which are hard to enforce at
compile-time". The counter-argument, as I understand, it was that
while the constraints may be hard to enforce at compile-time, they are
just as easy to enforce at run-time in a static language as in a
dynamic language, so that can't really be considered a *strength* per
se of dynamic languages. You then followed this up by issuing a
challenge to enforce this as a compile-type check in C++.

Obviously this has not been done [1], but just as obviously it could
not be done at compile-time in a dynamic language either, so I don't
see how any of this justifies your claim that being a static language
somehow makes constraints harder to enforce.

[1] But I have no doubt that it could be done in a language with a
sufficiently advanced type system. Just by way of example, the Haskell
wiki offers an example of quicksort implemented in the Haskell type
system: 
https://wiki.haskell.org/Type_arithmetic#An_Advanced_Example_:_Type-Level_Quicksort
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Are the critiques in "All the things I hate about Python" valid?

2018-02-20 Thread Steven D'Aprano
On Tue, 20 Feb 2018 14:12:08 +0100, Anders Wegge Keller wrote:

> På Tue, 20 Feb 2018 12:28:25 + (UTC) Steven D'Aprano
>  skrev:
>> On Mon, 19 Feb 2018 16:34:29 +0100, Anders Wegge Keller wrote:
>> 
>> > På Mon, 19 Feb 2018 15:15:19 + (UTC) Steven D'Aprano
>> >  skrev:
>> >> On Mon, 19 Feb 2018 14:06:36 +0100, Anders Wegge Keller wrote:
>> >>   
>>  [...]
>> >> 
>> >> That's a mighty powerful claim that goes against the documentation
>> >> for the array module. Can you back your claims up?
>> >> 
>> >> Here's an array and a list:
>> > 
>> >  Make me an array of tuples with two integers and a string, and we
>> >  can talk.
>> 
>> The array module's failure to support the specific type you want has no
>> bearing on whether or not Python is statically typed.
> 
>  You claimed Array could do what I requested, i.e. container type that
> guaranteed only one type inside.

And that's exactly what array does: it guarantees only one type inside. 
It doesn't happen to be the type you want (a tuple of two integers and a 
string), but that's irrelevant to the question of whether the arrays and 
their content are strongly typed or not.

If you want to say that array doesn't solve your problem, I have no 
argument with that. I'm not surprised: array is intentionally a very 
restricted type. I mentioned it as an example of something *similar* to 
what you want: a homogeneous sequence type with strong typing. I never 
said it would solve your (unknown, unstated) problems.

https://mail.python.org/pipermail/python-list/2018-February/730916.html



> Furthermore, you are misrepresenting C with malice.

Am I? With *malice* you say. What gives you such insight into my state of 
mind?

I don't think I've said very much about C except to say that it's known 
to not be type-safe. I don't think that ought to be controversial to 
anyone. C and C++ are well-known to be unsafe languages:

https://blog.regehr.org/archives/213

and type-safety is a subset of that. That's why there's so much interest 
in new languages like Go and Rust. But I also suggested that some level 
of type-unsafety is probably unavoidable for a systems language.

But okay, if I've misrepresented something about C, please explain, I'm 
happy to learn better.


>  I don't care why you feel that a simple observation is a personal
>  attack,

Who mentioned anything about a personal attack?

You're making technical claims that Python values aren't strongly typed. 
I think you're wrong, and said so, but offered to admit that *I* was 
wrong if you can demonstrate the correctness of your claims by actually 
changing the type of a list or array object in Python.

You've been unable to do so.

Rather than engage in good faith discussion, you're now trying to 
distract by making insinuations about my character (claiming I'm acting 
out of "malice", making me out to be complaining about "personal 
attacks") and now personal insults:

> but I see you behave as a spoiled kid.

> go and pout in your corner.


The bottom line is, you've made technical claims that you are unable to 
support. If you can back up those claims, then I will learn something. 
How about you?



-- 
Steve

-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Are the critiques in "All the things I hate about Python" valid?

2018-02-20 Thread Steven D'Aprano
On Tue, 20 Feb 2018 15:23:44 +0100, Antoon Pardon wrote:

>> Okay. Now create a constraint on a name in C++ such that it can only
>> accept integers representing A.D. years which, on the Gregorian
>> calendar, are leap years. (Using a dedicated integer-like type is
>> permitted.) It must accept all multiples of four, except those which
>> are multiples of one hundred, unless they're also multiples of four
>> hundred.
>>
>> That's what Steve asked for. Can you do it? Or is the C++ type system
>> not flexible enough for that?
> 
> Steve had multiple contributions in this thread. I didn't react to the
> one where he asked for that.

Yes you did: you refused to meet the challenge, stating (and I quote):

"Why should this be done at compile time?"

https://mail.python.org/pipermail/python-list/2018-February/730995.html



-- 
Steve

-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Are the critiques in "All the things I hate about Python" valid?

2018-02-20 Thread Antoon Pardon
On 20-02-18 14:58, Chris Angelico wrote:
> On Wed, Feb 21, 2018 at 12:53 AM, Antoon Pardon  wrote:
>> In C++ I can do something like:
>>
>>   SomeClass MyVar;
>>
>> And after that the kind of possible assignments to MyVar are constraint. It
>> makes the runtime throw an error when somewhere the program tries to assign
>> something to MyVar that isn't allowed by SomeClass.
>>
>> You can't put such constraints on names in Python.
>>
>> In C++ I can do some like:
>> Some_Class: MyVar;
>>
>> And after that, It will be impossible to assign a value to MyVar that
>> doesn't meet the
>> constraints imposed by the constructor/copy operator. You have put
>> somekind of
>> contract on the name MyVar, that limits the kind of things assignable to
>> it. You
>> can't put such constraints on a name in Python.
> Okay. Now create a constraint on a name in C++ such that it can only
> accept integers representing A.D. years which, on the Gregorian
> calendar, are leap years. (Using a dedicated integer-like type is
> permitted.) It must accept all multiples of four, except those which
> are multiples of one hundred, unless they're also multiples of four
> hundred.
>
> That's what Steve asked for. Can you do it? Or is the C++ type system
> not flexible enough for that?

Steve had multiple contributions in this thread. I didn't react to the
one where he asked for that.

I reacted to his assertion that dynamic languages excell at [run time
checks] as if static languages are somehow limited at run time checks.

writing a Digit Class in a dynamic language that checks whether the number
you are about to assign is a digit, doesn't strike me as that much different
from just writing a function that does the same kind of checking.

Plus, in a statically typed language you can put constraints on the variables
that will ensure the compilor will implicitly call the needed functions to
check (because they are part of the constructor/copy operator) which you
can't do in a dynamically typed language. So IMO the statically typed 
languages are at the advantage here.
-- 
Antoon.

-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Are the critiques in "All the things I hate about Python" valid?

2018-02-20 Thread Antoon Pardon
On 20-02-18 15:04, Paul Moore wrote:
> On 20 February 2018 at 13:53, Antoon Pardon  wrote:
>
>> You can't put such constraints on names in Python.
> I know. That's what *I* said some time ago.

So why did you bother complaining to me when I wrote it?


-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Are the critiques in "All the things I hate about Python" valid?

2018-02-20 Thread Antoon Pardon
On 20-02-18 14:55, Chris Angelico wrote:
> On Wed, Feb 21, 2018 at 12:38 AM, Antoon Pardon  wrote:
>> Why should this be done at compile time? I say a static language can do
>> the same as a dynamic language and your counter point is to ask for how
>> that static language can do something extra.
>>
>> The point I am making is that you claim dynamic languages are excelling
>> by being less demaning of the dynamic language.
>>
>> So yes the static language can check those kind of restraints at runtime
>> just as easily as a dynamic language.
> So what's the point of a "static language" if all it's doing is the
> same thing that any other language can do?

Who says that is all static languages are doing? Steven claimed dynamic 
languages
excelled at runtime checks. I counter by stating that statically typed languages
are just as good at runtime checks. How do you infer from that, that all
that statically languages do, is the same as a dynamic language? 

-- 
Antoon
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Are the critiques in "All the things I hate about Python" valid?

2018-02-20 Thread bartc

On 20/02/2018 13:38, Antoon Pardon wrote:


People praise the dynamic nature of Python here on this list and then
often enough seem to recoil when they see a piece of code really using
that dynamism.


Maybe everyone has their own ideas of how dynamic a language should be.


(I use another language that I call 'dynamic'. But the only dynamic 
thing is that variables have a dynamic type - the variable's type is a 
runtime attribute.


But, function names are static (they will always be function names). 
Module names are static. Type names (including user-defined ones) are 
static. Named constants are static. Source code is static (it only 
exists at compile-time). Attribute names are static; they have to be 
declared at compile-time. Variable names themselves are static: they 
can't become function or class or module names. Module imports are 
static (they are not done at runtime and can't be conditional). 
Operators are static and cannot overridden.


AFAIK, all these are dynamic in Python (not sure about operators).)

--
bartc
--
https://mail.python.org/mailman/listinfo/python-list


Re: Are the critiques in "All the things I hate about Python" valid?

2018-02-20 Thread Paul Moore
On 20 February 2018 at 13:53, Antoon Pardon  wrote:

> You can't put such constraints on names in Python.

I know. That's what *I* said some time ago.

>> Sigh. Languages are different. That's my point.
>
> So, if languages are different, why the difficulty in accepting one can
> do something the other can't?

I don't know. Who finds it difficult? I don't. What I find difficult
is understanding what you're saying other languages can do that I
haven't already agreed with.

>>  What's yours? If it's
>> that Python is worse than (some other language) then so what? Probably
>> true in some cases, but what makes you think you'll get enthusiastic
>> approval for such a statement in a Python group?
>
> So you only want to see praisal for python? One can't express how one
> prefers specific features from other languages?

Of course you can. Go right ahead.

Paul
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Are the critiques in "All the things I hate about Python" valid?

2018-02-20 Thread Chris Angelico
On Wed, Feb 21, 2018 at 12:53 AM, Antoon Pardon  wrote:
> In C++ I can do something like:
>
>   SomeClass MyVar;
>
> And after that the kind of possible assignments to MyVar are constraint. It
> makes the runtime throw an error when somewhere the program tries to assign
> something to MyVar that isn't allowed by SomeClass.
>
> You can't put such constraints on names in Python.
>
> In C++ I can do some like:
> Some_Class: MyVar;
>
> And after that, It will be impossible to assign a value to MyVar that
> doesn't meet the
> constraints imposed by the constructor/copy operator. You have put
> somekind of
> contract on the name MyVar, that limits the kind of things assignable to
> it. You
> can't put such constraints on a name in Python.

Okay. Now create a constraint on a name in C++ such that it can only
accept integers representing A.D. years which, on the Gregorian
calendar, are leap years. (Using a dedicated integer-like type is
permitted.) It must accept all multiples of four, except those which
are multiples of one hundred, unless they're also multiples of four
hundred.

That's what Steve asked for. Can you do it? Or is the C++ type system
not flexible enough for that?

ChrisA
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Are the critiques in "All the things I hate about Python" valid?

2018-02-20 Thread Chris Angelico
On Wed, Feb 21, 2018 at 12:38 AM, Antoon Pardon  wrote:
> Why should this be done at compile time? I say a static language can do
> the same as a dynamic language and your counter point is to ask for how
> that static language can do something extra.
>
> The point I am making is that you claim dynamic languages are excelling
> by being less demaning of the dynamic language.
>
> So yes the static language can check those kind of restraints at runtime
> just as easily as a dynamic language.

So what's the point of a "static language" if all it's doing is the
same thing that any other language can do?

The whole point of static analysis is that you can verify correctness
BEFORE something gets into production. That means you have the
potential to catch bugs before it's too late. If all you're going to
do is check everything at run time, it's not static analysis any more.
The question is: Can you create a strong compile-time type system that
can verify correctness WITHOUT running the code?

ChrisA
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Are the critiques in "All the things I hate about Python" valid?

2018-02-20 Thread Antoon Pardon
 I'm not proficient with C++, but IIUC, you could make a class in C++ and
 have the constructor and
 copy operator check for these kind of things. True it would be run-time
 checks but that would
 already be more than Python can give.
>>> That (run-time checks) is exactly the same as Python gives.
>> No it isn't exactly the same. Those runtime checks are implicit. They are 
>> like
>> a contract made at declaration time, which make it impossible to assign 
>> something
>> to the variable that doesn't meet the constraint without the program 
>> throwing an
>> error.
>>
>> You can't do something like that in Python.
> I *am* (reasonably) proficient in C++, and (other than the "values
> have types rather than variables/names" point I already stated was a
> difference in how the languages work) I don't see anything in what
> you're describing as "things C++ can do" that Python can't.

In C++ I can do something like:

  SomeClass MyVar;

And after that the kind of possible assignments to MyVar are constraint. It
makes the runtime throw an error when somewhere the program tries to assign
something to MyVar that isn't allowed by SomeClass.

You can't put such constraints on names in Python.

In C++ I can do some like:
    Some_Class: MyVar;

And after that, It will be impossible to assign a value to MyVar that
doesn't meet the
constraints imposed by the constructor/copy operator. You have put
somekind of
contract on the name MyVar, that limits the kind of things assignable to
it. You
can't put such constraints on a name in Python.
>
> Sigh. Languages are different. That's my point.

So, if languages are different, why the difficulty in accepting one can
do something the other can't?

>  What's yours? If it's
> that Python is worse than (some other language) then so what? Probably
> true in some cases, but what makes you think you'll get enthusiastic
> approval for such a statement in a Python group?

So you only want to see praisal for python? One can't express how one
prefers specific
features from other languages?


-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Are the critiques in "All the things I hate about Python" valid?

2018-02-20 Thread Antoon Pardon
On 20-02-18 13:24, Steven D'Aprano wrote:
> On Tue, 20 Feb 2018 12:18:47 +0100, Antoon Pardon wrote:
>
>> On 19-02-18 15:25, Steven D'Aprano wrote:
 Ones like C++ has already tied itself itself up in knots just doing
 the basics; I'm not sure how it would handle even my 1,3,5,7,9 type.

 But Python has classes and can do some of this stuff; how would it
 handle a numeric type that is constrained to be whole numbers within
 0..9 inclusive?
>>> This becomes easy at run-time:
>>>
>>> class Digit(int):
>>> def __new__(cls, arg):
>>> instance = super().__new__(cls, arg)
>>> if not 0 <= instance <= 9:
>>> raise ValueError('argument is out of range')
>>> return instance
>>>
>>> The above is obviously not a full-blown production-ready class. But it
>>> illustrates the basic concept. This is the sort of thing that dynamic
>>> languages excel at: enforcing constraints at run-time which are hard to
>>> enforce at compile-time.
>> I don't see how dynamic languages are excelling here. Writing code that
>> ensures a number of constraints can be done just as easily in a static
>> language.
> *Just* as easily? Really?
>
> Can you tell us which languages can enforce at compile-time that integer 
> N is a multiple of four but not a multiple of 100 unless it is also a 
> multiple of 400? (The same constraint as leap years.)

Why should this be done at compile time? I say a static language can do
the same as a dynamic language and your counter point is to ask for how
that static language can do something extra.

The point I am making is that you claim dynamic languages are excelling
by being less demaning of the dynamic language.

So yes the static language can check those kind of restraints at runtime
just as easily as a dynamic language.

> What type declaration would you write for that?
>
> Its easy to make overblown claims about how great static typing is, but 
> people didn't invent dynamically typed languages because they wanted to 
> program in a worse language. They did it because dynamic typing allows us 
> to do things which are hard, or impossible, in statically typed languages.

Maybe but you didn't give an example of something that is hard of impossible
in a statically typed language. There is nothing impossible or hard in checking
a number of constraints during runtime in a statically typed language.

> I agree that Pascal-style interval types are nice, but they're also 
> limited to intervals, and *integer* intervals at that. Pascal doesn't 
> support floating point ranges, such as "x is a Real between 0 and 1".
>
> How would you write a type declaration for numbers like these:
>
> 4, 6, 8, 24, 26, 48, 50, 124, 126, 342, 344, ... 3909821048582988050
>
> in the language of your choice?
>
> Yes, there is a pattern: one less than, and one more than, powers of 5 
> and 7, up to a maximum of 2**64.
>
> That is, 5±1, 25±1, 125±1, ... 7±1, 49±1, 343±1, ...

Well as far as I know you could do this in C++ by having the constructor and
copy-operator make the needed checks.

> Its one thing to say that a type system could enforce this at compile-
> time. Its another to demonstrate an existing type system which actually 
> does.

I am not talking about compile time. There is nothing that prevents a
statically typed language to do some of the checks at runtime.

>> Each assignment to x would then implicitly do something like an assert
>> to checks the constraint,
>> so it would be impossible to ever assign 11 to x, without an error being
>> thrown.
> As I remember it, Pascal range checking is just dynamic typing in 
> disguise. Statically, x is just an integer, with no interval checking 
> performed at compile-time except for assignment by literals. Everything 
> else is run-time range checking.

So? As far as I know Pascal is generally considered a statically typed
language. That some of the constraints imposed by the type can only
be checked at runtime doesn't contradict that the type of a variable
is determined at compile time.

> Of course you're right that Python won't stop you assigning (say) a float 
> to x. On the other hand, Pascal and C won't allow you to assign a string 
> to something which previously was an integer. The need to create new 
> labels for things just to placate the compiler is one of the more 
> annoying things about static typing. Yes, x was a number, now its a 
> string. If *I* can keep track of that, why can't the compiler?

Is it really that annoying? Most examples I have seen here where the
same variable was assigned multiple types, was labeled a code smell
that needed to be approved by review or something like that, on this list.

People praise the dynamic nature of Python here on this list and then
often enough seem to recoil when they see a piece of code really using
that dynamism.

-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Are the critiques in "All the things I hate about Python" valid?

2018-02-20 Thread Paul Moore
On 20 February 2018 at 13:04, Antoon Pardon  wrote:
> On 20-02-18 13:11, Paul Moore wrote:
>> On 20 February 2018 at 11:18, Antoon Pardon  wrote:
>>> Personnally I would prefer the type system of Pascal and Modula2 with
>>> their interval type
>>> above a Digit class in python. For the simple reason that once you had
>>> declared a variable
>>> like this:
>>> x: 1 .. 10;
>>>
>>> Each assignment to x would then implicitly do something like an assert
>>> to checks the constraint,
>>> so it would be impossible to ever assign 11 to x, without an error being
>>> thrown.
>>>
>>> There is no such possibility in Python. You can off course start with x
>>> = Digit(5), but the language
>>> won't stop you from doing x = 11 later.
>> All that is saying is that in Pascal, variables have types, whereas in
>> Python values have types but variables (names ;-)) don't. It's true,
>> but not particularly important in toy examples like this. In larger
>> scale programs, tracking the "type" of what gets assigned to a
>> variable can be really useful, and carefully managed types can help
>> with this. Pascal/Modula2 (and C/C++) have the compiler do this,
>> Python has a separate tool (MyPy).
>
> In Pascal and Modula2 type checking was not limited to compile time. Part
> of that type checking was done at by the runtime enviroment.

So? What point are you making? (I genuinely don't see - you surely
aren't saying that Python can't implement runtime checks, and this is
all related to your original comment that "There is no such
possibility in Python").

>>> I'm not proficient with C++, but IIUC, you could make a class in C++ and
>>> have the constructor and
>>> copy operator check for these kind of things. True it would be run-time
>>> checks but that would
>>> already be more than Python can give.
>> That (run-time checks) is exactly the same as Python gives.
>
> No it isn't exactly the same. Those runtime checks are implicit. They are like
> a contract made at declaration time, which make it impossible to assign 
> something
> to the variable that doesn't meet the constraint without the program throwing 
> an
> error.
>
> You can't do something like that in Python.

I *am* (reasonably) proficient in C++, and (other than the "values
have types rather than variables/names" point I already stated was a
difference in how the languages work) I don't see anything in what
you're describing as "things C++ can do" that Python can't.

Sigh. Languages are different. That's my point. What's yours? If it's
that Python is worse than (some other language) then so what? Probably
true in some cases, but what makes you think you'll get enthusiastic
approval for such a statement in a Python group?

Bored now.

Paul
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Are the critiques in "All the things I hate about Python" valid?

2018-02-20 Thread Anders Wegge Keller
På Tue, 20 Feb 2018 12:28:25 + (UTC)
Steven D'Aprano  skrev:
> On Mon, 19 Feb 2018 16:34:29 +0100, Anders Wegge Keller wrote:
> 
> > På Mon, 19 Feb 2018 15:15:19 + (UTC) Steven D'Aprano
> >  skrev:  
> >> On Mon, 19 Feb 2018 14:06:36 +0100, Anders Wegge Keller wrote:
> >>   
>  [...]  
> >> 
> >> That's a mighty powerful claim that goes against the documentation for
> >> the array module. Can you back your claims up?
> >> 
> >> Here's an array and a list:  
> > 
> >  Make me an array of tuples with two integers and a string, and we can
> >  talk.  
> 
> The array module's failure to support the specific type you want has no 
> bearing on whether or not Python is statically typed.

 You claimed Array could do what I requested, i.e. container type that
guaranteed only one type inside. Furthermore, you are misrepresenting C with
malice. 

 I don't care why you feel that a simple observation is a personal attack,
but I see you behave as a spoiled kid. I haven\t got the time for it, sop go
and pout in your corner. 

-- 
//Wegge
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Are the critiques in "All the things I hate about Python" valid?

2018-02-20 Thread Antoon Pardon
On 20-02-18 13:11, Paul Moore wrote:
> On 20 February 2018 at 11:18, Antoon Pardon  wrote:
>> Personnally I would prefer the type system of Pascal and Modula2 with
>> their interval type
>> above a Digit class in python. For the simple reason that once you had
>> declared a variable
>> like this:
>> x: 1 .. 10;
>>
>> Each assignment to x would then implicitly do something like an assert
>> to checks the constraint,
>> so it would be impossible to ever assign 11 to x, without an error being
>> thrown.
>>
>> There is no such possibility in Python. You can off course start with x
>> = Digit(5), but the language
>> won't stop you from doing x = 11 later.
> All that is saying is that in Pascal, variables have types, whereas in
> Python values have types but variables (names ;-)) don't. It's true,
> but not particularly important in toy examples like this. In larger
> scale programs, tracking the "type" of what gets assigned to a
> variable can be really useful, and carefully managed types can help
> with this. Pascal/Modula2 (and C/C++) have the compiler do this,
> Python has a separate tool (MyPy).

In Pascal and Modula2 type checking was not limited to compile time. Part
of that type checking was done at by the runtime enviroment.

>> I'm not proficient with C++, but IIUC, you could make a class in C++ and
>> have the constructor and
>> copy operator check for these kind of things. True it would be run-time
>> checks but that would
>> already be more than Python can give.
> That (run-time checks) is exactly the same as Python gives.

No it isn't exactly the same. Those runtime checks are implicit. They are like
a contract made at declaration time, which make it impossible to assign 
something
to the variable that doesn't meet the constraint without the program throwing an
error.

You can't do something like that in Python.

-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Are the critiques in "All the things I hate about Python" valid?

2018-02-20 Thread bartc

On 20/02/2018 12:11, Paul Moore wrote:

On 20 February 2018 at 11:18, Antoon Pardon  wrote:



There is no such possibility in Python. You can off course start with x
= Digit(5), but the language
won't stop you from doing x = 11 later.



I'm not proficient with C++, but IIUC, you could make a class in C++ and
have the constructor and
copy operator check for these kind of things. True it would be run-time
checks but that would
already be more than Python can give.


I don't know if that counts. In Pascal (and presumably Ada) then all the 
gubbins need to make this work properly:


  var x: 1..10;

  x = 10;
  x = x + 1;   { error? }

would already be in place. Trying to emulate that within a language is 
complex and unwieldy, and someone has to know how to do it, and then do 
it. If someone else creates an add-on for it, then those tend to be 
large and cumbersome (because they have to have every conceivable bell 
and whistle). And it's an extra dependency.


The end result: if I wanted to sit down right now and have a variable 
and/or type in Python or C++ that is constrained to be within 1..10, 
then I couldn't. I'd have to use a generic integer type.


And in fact, in Python, I couldn't even do that, as I can assign 
anything at all to x.


This is not necessarily undesirable: part of the point of dynamic 
languages is being informal and having less discipline imposed so that 
things can get done more rapidly. But enforced discipline can also be 
useful.



It's somewhat unrelated (scoping is a different topic than assignment)
but you can do

{
 int x = 2;
 {
 char *x = "hello";
 }
}

in C, so names can have different types even in C (it's just
variables, or names within a specific scope, that have types
associated with them).


That's scope; Python has that too. (Although not C's block scopes and 
its bizarre rules which mean that you can have up 5 different 'x' 
meanings even within the same block. And an unlimited number of 'x' 
scopes within the same function.


(This is allowed in C:   int L; L: L=10; goto L; )

--
bartc
--
https://mail.python.org/mailman/listinfo/python-list


Re: Are the critiques in "All the things I hate about Python" valid?

2018-02-20 Thread Steven D'Aprano
On Mon, 19 Feb 2018 16:34:29 +0100, Anders Wegge Keller wrote:

> På Mon, 19 Feb 2018 15:15:19 + (UTC) Steven D'Aprano
>  skrev:
>> On Mon, 19 Feb 2018 14:06:36 +0100, Anders Wegge Keller wrote:
>> 
>> > Array is not even close to providing a strongly typed container.
>> 
>> That's a mighty powerful claim that goes against the documentation for
>> the array module. Can you back your claims up?
>> 
>> Here's an array and a list:
> 
>  Make me an array of tuples with two integers and a string, and we can
>  talk.

The array module's failure to support the specific type you want has no 
bearing on whether or not Python is statically typed.

The question isn't "does Python provide you with every imaginable 
homogeneous array type you might ever want?", we already know the answer 
to that is no.

The question is your claim that Python objects aren't strongly typed, and 
your obvious attempt to avoid answering my challenge is answer enough. If 
you could meet the challenge, you would have done it.



-- 
Steve

-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Are the critiques in "All the things I hate about Python" valid?

2018-02-20 Thread Steven D'Aprano
On Tue, 20 Feb 2018 12:18:47 +0100, Antoon Pardon wrote:

> On 19-02-18 15:25, Steven D'Aprano wrote:
>>
>>> Ones like C++ has already tied itself itself up in knots just doing
>>> the basics; I'm not sure how it would handle even my 1,3,5,7,9 type.
>>>
>>> But Python has classes and can do some of this stuff; how would it
>>> handle a numeric type that is constrained to be whole numbers within
>>> 0..9 inclusive?
>> This becomes easy at run-time:
>>
>> class Digit(int):
>> def __new__(cls, arg):
>> instance = super().__new__(cls, arg)
>> if not 0 <= instance <= 9:
>> raise ValueError('argument is out of range')
>> return instance
>>
>> The above is obviously not a full-blown production-ready class. But it
>> illustrates the basic concept. This is the sort of thing that dynamic
>> languages excel at: enforcing constraints at run-time which are hard to
>> enforce at compile-time.
> 
> I don't see how dynamic languages are excelling here. Writing code that
> ensures a number of constraints can be done just as easily in a static
> language.

*Just* as easily? Really?

Can you tell us which languages can enforce at compile-time that integer 
N is a multiple of four but not a multiple of 100 unless it is also a 
multiple of 400? (The same constraint as leap years.)

What type declaration would you write for that?

Its easy to make overblown claims about how great static typing is, but 
people didn't invent dynamically typed languages because they wanted to 
program in a worse language. They did it because dynamic typing allows us 
to do things which are hard, or impossible, in statically typed languages.


> Personnally I would prefer the type system of Pascal and Modula2 with
> their interval type
> above a Digit class in python. For the simple reason that once you had
> declared a variable
> like this:
>     x: 1 .. 10;


I agree that Pascal-style interval types are nice, but they're also 
limited to intervals, and *integer* intervals at that. Pascal doesn't 
support floating point ranges, such as "x is a Real between 0 and 1".

How would you write a type declaration for numbers like these:

4, 6, 8, 24, 26, 48, 50, 124, 126, 342, 344, ... 3909821048582988050

in the language of your choice?

Yes, there is a pattern: one less than, and one more than, powers of 5 
and 7, up to a maximum of 2**64.

That is, 5±1, 25±1, 125±1, ... 7±1, 49±1, 343±1, ...

Its one thing to say that a type system could enforce this at compile-
time. Its another to demonstrate an existing type system which actually 
does.


> Each assignment to x would then implicitly do something like an assert
> to checks the constraint,
> so it would be impossible to ever assign 11 to x, without an error being
> thrown.

As I remember it, Pascal range checking is just dynamic typing in 
disguise. Statically, x is just an integer, with no interval checking 
performed at compile-time except for assignment by literals. Everything 
else is run-time range checking.

By which I mean, the compiler would complain if you tried:

var
  x: 1 .. 10;
begin
  x := 11;
end;

but it would allow this:

var
  a, b: integer;
  x: 1 .. 10;
begin
  a := 10;
  b := 1;
  x := a + b;
end;

However, the second would generate a runtime range check error and halt 
the program.

That at least is how the Lightspeed Pascal (later Think Pascal) compiler 
on the Apple Mac operated, and as far as I know all other Pascal 
compilers worked the same.

Now that was over 30 years ago, and I daresay that type checkers these 
days are more sophisticated and powerful than Pascal's pretty simple 
checker. But still, there's only so much you can do at compile-time.


> There is no such possibility in Python. You can off course start with x
> = Digit(5), but the language
> won't stop you from doing x = 11 later.


Of course you're right that Python won't stop you assigning (say) a float 
to x. On the other hand, Pascal and C won't allow you to assign a string 
to something which previously was an integer. The need to create new 
labels for things just to placate the compiler is one of the more 
annoying things about static typing. Yes, x was a number, now its a 
string. If *I* can keep track of that, why can't the compiler?


> I'm not proficient with C++, but IIUC, you could make a class in C++ and
> have the constructor and
> copy operator check for these kind of things. True it would be run-time
> checks but that would
> already be more than Python can give.

Sure. Its a different approach, and not without its merits.



-- 
Steve

-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Are the critiques in "All the things I hate about Python" valid?

2018-02-20 Thread Paul Moore
On 20 February 2018 at 11:18, Antoon Pardon  wrote:
> Personnally I would prefer the type system of Pascal and Modula2 with
> their interval type
> above a Digit class in python. For the simple reason that once you had
> declared a variable
> like this:
> x: 1 .. 10;
>
> Each assignment to x would then implicitly do something like an assert
> to checks the constraint,
> so it would be impossible to ever assign 11 to x, without an error being
> thrown.
>
> There is no such possibility in Python. You can off course start with x
> = Digit(5), but the language
> won't stop you from doing x = 11 later.

All that is saying is that in Pascal, variables have types, whereas in
Python values have types but variables (names ;-)) don't. It's true,
but not particularly important in toy examples like this. In larger
scale programs, tracking the "type" of what gets assigned to a
variable can be really useful, and carefully managed types can help
with this. Pascal/Modula2 (and C/C++) have the compiler do this,
Python has a separate tool (MyPy). Early C compilers used to have
linters that did some checks outside of the compiler - maybe someday
Python will build MyPy into the compiler (although I suspect not).

Also, tracking "types" is only half the battle. There are probably
very few people who have never mistakenly assigned NULL to a pointer
in C that shouldn't be null. Or even in Java, which is supposed to not
allow things like that. And tracking const types in C is widely
acknowledged to be a mixed blessing at best. Where does "type" end and
"documented constraint or programming contract" start?

> I'm not proficient with C++, but IIUC, you could make a class in C++ and
> have the constructor and
> copy operator check for these kind of things. True it would be run-time
> checks but that would
> already be more than Python can give.

That (run-time checks) is exactly the same as Python gives. In C++,
variables have types so you could ensure that you could only assign a
value of your digit type to a given variable, but as I said above
that's a separate point.

It's somewhat unrelated (scoping is a different topic than assignment)
but you can do

{
int x = 2;
{
char *x = "hello";
}
}

in C, so names can have different types even in C (it's just
variables, or names within a specific scope, that have types
associated with them).

Summary: Different programming languages have different semantics.
Which really isn't that surprising...

Paul
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Are the critiques in "All the things I hate about Python" valid?

2018-02-20 Thread Antoon Pardon
On 19-02-18 15:25, Steven D'Aprano wrote:
>
>> Ones like C++ has already tied itself itself up in knots just doing the
>> basics; I'm not sure how it would handle even my 1,3,5,7,9 type.
>>
>> But Python has classes and can do some of this stuff; how would it
>> handle a numeric type that is constrained to be whole numbers within
>> 0..9 inclusive?
> This becomes easy at run-time:
>
> class Digit(int):
> def __new__(cls, arg):
> instance = super().__new__(cls, arg)
> if not 0 <= instance <= 9:
> raise ValueError('argument is out of range')
> return instance
>
> The above is obviously not a full-blown production-ready class. But it 
> illustrates the basic concept. This is the sort of thing that dynamic 
> languages excel at: enforcing constraints at run-time which are hard to 
> enforce at compile-time.

I don't see how dynamic languages are excelling here. Writing code that
ensures a number
of constraints can be done just as easily in a static language.

Personnally I would prefer the type system of Pascal and Modula2 with
their interval type
above a Digit class in python. For the simple reason that once you had
declared a variable
like this:
    x: 1 .. 10;

Each assignment to x would then implicitly do something like an assert
to checks the constraint,
so it would be impossible to ever assign 11 to x, without an error being
thrown.

There is no such possibility in Python. You can off course start with x
= Digit(5), but the language
won't stop you from doing x = 11 later.

I'm not proficient with C++, but IIUC, you could make a class in C++ and
have the constructor and
copy operator check for these kind of things. True it would be run-time
checks but that would
already be more than Python can give.

-- 
Antoon.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Are the critiques in "All the things I hate about Python" valid?

2018-02-20 Thread Ned Batchelder

On 2/20/18 5:47 AM, Antoon Pardon wrote:

On 19-02-18 16:18, Ned Batchelder wrote:

On 2/19/18 9:54 AM, Steven D'Aprano wrote:

On Mon, 19 Feb 2018 13:28:26 +, Paul Moore wrote:


[1] The most basic question, which people making such claims often
can't
answer, is "Do you mean that values are strongly typed, or that names
are? Or did you mean that variables are, because if so Python doesn't
even have variables in the sense that you mean" Programming language
semantics are complex.

An excellent point.

The distinction between typing *values* and *names* is a good one.




I guess I'll have to continue to grit my teeth as people say, "Python
doesn't have variables."   Why can't we say, "Python's variables work
differently than other languages"?

--Ned.

Which other languages. It seems python variables seem to work just like
lisp, scheme and smalltalk.


C.

That is one of the reasons for my frustration: the "Python has no 
variables" slogan is incredibly C-centric.  I understand the importance 
of C, and in the early days of Python, there was good reason to assume 
that people were familiar with C.  These days, there are far more 
mainstream languages that work just as Python does.


To your "work just like" list we can add Javascript, Ruby, PHP, and Java 
(for objects, not primitives).


--Ned.
--
https://mail.python.org/mailman/listinfo/python-list


Re: Are the critiques in "All the things I hate about Python" valid?

2018-02-20 Thread Antoon Pardon
On 19-02-18 16:18, Ned Batchelder wrote:
> On 2/19/18 9:54 AM, Steven D'Aprano wrote:
>> On Mon, 19 Feb 2018 13:28:26 +, Paul Moore wrote:
>>
>>> [1] The most basic question, which people making such claims often
>>> can't
>>> answer, is "Do you mean that values are strongly typed, or that names
>>> are? Or did you mean that variables are, because if so Python doesn't
>>> even have variables in the sense that you mean" Programming language
>>> semantics are complex.
>> An excellent point.
>>
>> The distinction between typing *values* and *names* is a good one.
>>
>>
>>
>
> I guess I'll have to continue to grit my teeth as people say, "Python
> doesn't have variables."   Why can't we say, "Python's variables work
> differently than other languages"?
>
> --Ned.

Which other languages. It seems python variables seem to work just like
lisp, scheme and smalltalk.

-- 
Antoon

-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Are the critiques in "All the things I hate about Python" valid?

2018-02-20 Thread Steven D'Aprano
On Tue, 20 Feb 2018 02:35:37 +1100, Chris Angelico wrote:

>  But C is a language saddled with so much history and backward
> compatibility constraints that there are some things you just CAN'T make
> into errors

Indeed. C is not even close to a safe language, hence the move to create 
(and more importantly, convince people to use!) systems languages like 
Rust and D which combine C's ability to generate fast code without 
(unnecessarily) compromising type safety.



-- 
Steve

-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Are the critiques in "All the things I hate about Python" valid?

2018-02-19 Thread breamoreboy
On Monday, February 19, 2018 at 1:07:02 PM UTC, Anders Wegge Keller wrote:
> På Mon, 19 Feb 2018 04:39:31 + (UTC)
> Steven D'Aprano skrev:
> > On Mon, 19 Feb 2018 04:26:32 +0100, Anders Wegge Keller wrote:
> > 
> > > På Mon, 19 Feb 2018 08:47:14 +1100
> > > Tim Delaney skrev:  
> > >> On 18 February 2018 at 22:55, Anders Wegge Keller 
> > >> wrote:  
> > > 
> > >   
> >  [...]  
> > >   
> > >> You couldn't have got the above much more wrong.  
> > >
> > >> As others have said, typing is about how the underlying memory is
> > >> treated.  
> > > 
> > >  And that is exactly my point. Python does not have a typed list. It
> > >  have a list that takes whatever is thrown into it.
> > > 
> > >  I'll skip the rest, as you totally missed the point.  
> > 
> > I think its actually you have totally missed the point. What you want is 
> > a homogeneous list, a list which only accepts items of the same type. The 
> > built-in list is not that data structure, but Python already has 
> > something similar: see the array module.
> 
>  Given that I'm the one making a point about the unwarranted smugness, I
> know that I'm not missing anything. Array is not even close to providing a
> strongly typed container. For all of the yakking about other languages
> weak, blah, BCPL, blah, I still wonder where that need to feel superior to
> anything else comes from.  
> 
>  Python isn't particular strong typed. In fact, apart from asking an object
> what type it is, types are not that important. It's the interface that
> matters. I wonder why this is a sore point for Python developers?
> 
> 
> -- 
> //Wegge

Congratulations, you're the first new person I've had on my Dream Team for some 
months, fresh blood is always so welcome.

--
Kindest regards.

Mark Lawrence.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Are the critiques in "All the things I hate about Python" valid?

2018-02-19 Thread Rick Johnson
On Saturday, February 17, 2018 at 12:58:49 AM UTC-6, Paul Rubin wrote:
[...]
> Beyond that, the Python community (with some exceptions) seems to have a
> widespread hatred of threads.  It instead prefers to handle concurrent
> i/o with in-thread async schemes that the rest of the world left behind
> in the 1960s.  

Hmm... and many wonder if the source of that hatred is a direct result of
CPython's unholy alliance with the GIL?
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Are the critiques in "All the things I hate about Python" valid?

2018-02-19 Thread Rick Johnson
On Friday, February 16, 2018 at 10:25:32 PM UTC-6, Chris Angelico wrote:
[...]
> This is often touted as a necessity for industrial-grade
> software. It isn't. There are many things that a type
> system, no matter how sophisticated, cannot catch; for some
> reason, though, we don't hear people saying "C is useless
> for industrial-grade software because it doesn't have
> function contracts".

And likewise, there are many problems that a seatbelt cannot
protect you against -- like for instance: a car-jacker
shooting you in the head at point-blank range. But we don't
throw the baby out with the bath water, do we?

> Anyway, if you want some system of type checking, you can
> use static analysis (eg tools like MyPy) to go over your
> code the same way a compiler might.

Are you suggesting this project for std-lib inclusion?

> "The first glaring issue is that I have no guarantee that
> is_valid() returns a bool type." -- huh? It's being used in
> a boolean context, and it has a name that starts "is_". How
> much guarantee are you looking for? *ANY* object can be
> used in an 'if', so it doesn't even matter. This is a
> stupidly contrived criticism.
> 
> > Python markets itself as a dynamically-typed programming
> > language, similar to Perl, Ruby, or JavaScript. The word
> > “dynamically typed” has a positive connotation, more so
> > than “weakly typed.” Conversely, the word “strongly typed”
> > sounds more positive than saying “statically typed.”
> 
> Those are all different terms, and all of them are
> misunderstood. They're not synonyms.

The author was underscoring the unfortunate psychological
semantics at play when words like "strong" are juxtaposed
with words like "weak". Sadly, old boy, i believe you've
missed the point!

> > Python ships with a threading module; but due to how the
> > Python interpreter is implemented, it can only ever run
> > one thread at a time. This is due to the infamous Global
> > Interpreter Lock (GIL). In an age when the only computers
> > around had a single core, this was nothing to fuss over.
> 
> Totally not true. The GIL does not stop other threads from
> running. Also, Python has existed for multiple CPU systems
> pretty much since its inception, I believe. (Summoning the
> D'Aprano for history lesson?)

Unfortunately "D'App-ran?...Oh!" is still debugging his hello
world program. He'll be along later. Or never... Whichever
comes /last/.

[...]


-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Are the critiques in "All the things I hate about Python" valid?

2018-02-19 Thread Richard Damon

On 2/19/18 10:35 AM, Chris Angelico wrote:

On Tue, Feb 20, 2018 at 12:34 AM, Steven D'Aprano
 wrote:

On Mon, 19 Feb 2018 20:14:32 +1100, Chris Angelico wrote:


As an integer, 3.141590 is 107853 $

Looks to me like C is perfectly happy to interpret a float as an int.

Yes, but that's not an *automatic* coercion. To count as weakly typed,
the compiler has to do it automatically, without an explicit cast or
conversion.

Fair enough. If you ignore warnings, then C does have that kind of weak typing:

$ cat demo.c
#include 

int main() {
 float f = 3.14159;
 int *i = 
 printf("As an integer, %f is %d\n", f, *i);
 return 0;
}

$ gcc demo.c
demo.c: In function ‘main’:
demo.c:5:14: warning: initialization from incompatible pointer type
[-Wincompatible-pointer-types]
  int *i = 
   ^
$

GCC was quite happy to compile that code, even though the type of ""
is "pointer to float", and it's being assigned to a variable of type
"pointer to int". But C is a language saddled with so much history and
backward compatibility constraints that there are some things you just
CAN'T make into errors; so in terms of "how safe is C?", I'd have to
say that warnings (especially those that are enabled by default - I
didn't need to say "-Wall" for this test), count as "disallowing",
especially if all the major compilers emit warnings on the same code.
But I do see the argument that "it compiles, so the language clearly
permits it".

ChrisA


One thing to note, that is more an issue with GCC than with C. By the 
standard, that is a constraint violation, that requires a diagnostic, 
and the C standard says it provides no definition of what should happen 
here, which is about as strong as it gets to defining something as an 
'Error', the only thing with a stronger requirement is the #error 
statement which must not running the program.


GCC has decided that this diagnostic will be considered just a 'Warning' 
and provides its own meaning to the statement. You really want to run 
with pedantic-errors enabled to get GCC to reject code with constraint 
violations.


--
Richard Damon

--
https://mail.python.org/mailman/listinfo/python-list


Re: Are the critiques in "All the things I hate about Python" valid?

2018-02-19 Thread Ned Batchelder

On 2/19/18 1:01 PM, Paul Moore wrote:

On 19 February 2018 at 17:11, Ned Batchelder  wrote:

On 2/19/18 10:39 AM, Paul Moore wrote:

I'm curious - How would you explain Python's "variables" to someone
who knows how C variables work, in a way that ensures they don't carry
across any unfortunate misconceptions based on how C works? If I had a
good way of doing that, maybe I wouldn't need to play apple/orange
games when discussing the subject.

I would (and did) explain it like this:
https://nedbatchelder.com/text/names1.html

That talk was pretty much powered by hating the phrase "Python has no
variables" :)

Interesting (and somewhat embarrassing :-() That talk (which I'd
forgotten was yours) was one of the key things that made me start
thinking in terms of Python naming values rather than assigning values
to variables! I still find that your explanation (which never uses the
term "variable" until you refer to the "Python has no variables" idea
at the end) is one of the best ways to describe how Python assignment
works.

But using your explanation as a way to defend a statement that you
don't agree with is wrong, so I'll stop doing that in future. Sorry!

In terms of your talk, would I be right to say that "names" (in the
sense you use them in that talk) are Python's "variables"? That
equates to common usage, so I can go with that ("Python's variables
act like names, unlike other languages"). But I'd hate to replace one
misunderstanding of what you said with another, so let me know if I've
still got it wrong...


TBH, I forget the exact words I used during the talk, but: names are 
Python's variables. That sounds good to me.


--Ned.

--
https://mail.python.org/mailman/listinfo/python-list


Re: Are the critiques in "All the things I hate about Python" valid?

2018-02-19 Thread Paul Moore
On 19 February 2018 at 17:11, Ned Batchelder  wrote:
> On 2/19/18 10:39 AM, Paul Moore wrote:
>>
>> I'm curious - How would you explain Python's "variables" to someone
>> who knows how C variables work, in a way that ensures they don't carry
>> across any unfortunate misconceptions based on how C works? If I had a
>> good way of doing that, maybe I wouldn't need to play apple/orange
>> games when discussing the subject.
>
> I would (and did) explain it like this:
> https://nedbatchelder.com/text/names1.html
>
> That talk was pretty much powered by hating the phrase "Python has no
> variables" :)

Interesting (and somewhat embarrassing :-() That talk (which I'd
forgotten was yours) was one of the key things that made me start
thinking in terms of Python naming values rather than assigning values
to variables! I still find that your explanation (which never uses the
term "variable" until you refer to the "Python has no variables" idea
at the end) is one of the best ways to describe how Python assignment
works.

But using your explanation as a way to defend a statement that you
don't agree with is wrong, so I'll stop doing that in future. Sorry!

In terms of your talk, would I be right to say that "names" (in the
sense you use them in that talk) are Python's "variables"? That
equates to common usage, so I can go with that ("Python's variables
act like names, unlike other languages"). But I'd hate to replace one
misunderstanding of what you said with another, so let me know if I've
still got it wrong...

Paul
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Are the critiques in "All the things I hate about Python" valid?

2018-02-19 Thread Ned Batchelder

On 2/19/18 10:39 AM, Paul Moore wrote:

On 19 February 2018 at 15:18, Ned Batchelder  wrote:

On 2/19/18 9:54 AM, Steven D'Aprano wrote:

On Mon, 19 Feb 2018 13:28:26 +, Paul Moore wrote:


[1] The most basic question, which people making such claims often can't
answer, is "Do you mean that values are strongly typed, or that names
are? Or did you mean that variables are, because if so Python doesn't
even have variables in the sense that you mean" Programming language
semantics are complex.

An excellent point.

The distinction between typing *values* and *names* is a good one.


I guess I'll have to continue to grit my teeth as people say, "Python
doesn't have variables."   Why can't we say, "Python's variables work
differently than other languages"?

Apologies, Ned. I didn't mean to make your teeth sore :-)

I've found that when people refer to "variables" they pretty much
inevitably have a picture in their mind of a named box that "contains"
a value (or pointer to a value). They find it difficult to understand
that Python doesn't have those boxes but rather names the values
directly. Sort of. And yes, that 's very much "sort of". It's
certainly just as viable to say to people that Python's idea of
variables is different than (say) C's, but in my experience you end up
qualifying so much that it's easier to use a different term without
the connotations. Sort of like saying "I like apples - the orange ones
that are a type of citrus fruit" :-)

In common usage I'll happily use the terms "variable" and "name"
somewhat interchangeably, but when things degenerate into detail-level
picking over specifics, I avoid doing so. I was wrong to casually say
"Python doesn't have variables", though - if I want to be detailed and
specific, I should make sure my writing reflects that that's what I'm
doing.

I'm curious - How would you explain Python's "variables" to someone
who knows how C variables work, in a way that ensures they don't carry
across any unfortunate misconceptions based on how C works? If I had a
good way of doing that, maybe I wouldn't need to play apple/orange
games when discussing the subject.


I would (and did) explain it like this: 
https://nedbatchelder.com/text/names1.html


That talk was pretty much powered by hating the phrase "Python has no 
variables" :)


--Ned.


Paul


--
https://mail.python.org/mailman/listinfo/python-list


Re: Are the critiques in "All the things I hate about Python" valid?

2018-02-19 Thread Marko Rauhamaa
Paul Moore :

> I'm curious - How would you explain Python's "variables" to someone
> who knows how C variables work, in a way that ensures they don't carry
> across any unfortunate misconceptions based on how C works?

Just say that

 1. Every Python variable is of the type "Object *".

 2. Every Python expression evaluates to a pointer (Object *).

 3. Python's "." is equivalent to C's "->".

That'll get the main point across pretty fast.


Marko
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Are the critiques in "All the things I hate about Python" valid?

2018-02-19 Thread Chris Angelico
On Mon, Feb 19, 2018 at 11:35 PM, bartc  wrote:
> Sometimes, the reason for creating a special numerical type is precisely so
> you can't do arithmetic on them, if it's not meaningful for the type.
>
> So the special type of the values 65..90 might not allow the type be
> multiplied or divided, or added to itself. Because they represent characters
> A..Z. Or house numbers. Or the age of pensioners. (You'd need to convert to
> ordinary integers, is that is allowed.)

If they represent characters, then they're not integers. They're
characters. Characters are not integers.

House numbers and pensioners' ages are not unitless numbers. If you
truly want to represent these as actual types, then you need to
incorporate the unit in the type, or have a generic "number and unit"
data type. That would then change the operations permitted on that
type.

None of this says anything about the original question, which was
about numbers. Actual, plain, ordinary integers.

>>  there's no
>> requirement for the result of an operation to have the same type as
>> its inputs:
>>
> 5 / 2 # two integers
>>
>> 2.5
>
> Try that when the type of {1..13} represents playing card ordinal values.

And now you're pretending that an enumeration is the same thing as an
integer. You're arguing about a type system, then trying to claim that
everything that can be represented as an integer must be an integer.
Your position is illogical.

> But Python has classes and can do some of this stuff; how would it handle a
> numeric type that is constrained to be whole numbers within 0..9 inclusive?

Do you mean that arithmetic results have to also be constrained, or
that the numeric type must itself only be those few? You could fairly
easily define a data type like this:

Int[0:10] # integer 0...9 inclusive (0..10 inc/exc)
Int[0:10] + Int[0:10] ==> Int[0:19]
Int[0:10] * Int[0:10] ==> Int[0:81]
Int[0:10] / Int[1:10] ==> Fraction

Perfectly sane and useful.

ChrisA
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Are the critiques in "All the things I hate about Python" valid?

2018-02-19 Thread Paul Moore
On 19 February 2018 at 15:18, Ned Batchelder  wrote:
> On 2/19/18 9:54 AM, Steven D'Aprano wrote:
>>
>> On Mon, 19 Feb 2018 13:28:26 +, Paul Moore wrote:
>>
>>> [1] The most basic question, which people making such claims often can't
>>> answer, is "Do you mean that values are strongly typed, or that names
>>> are? Or did you mean that variables are, because if so Python doesn't
>>> even have variables in the sense that you mean" Programming language
>>> semantics are complex.
>>
>> An excellent point.
>>
>> The distinction between typing *values* and *names* is a good one.
>>
>
> I guess I'll have to continue to grit my teeth as people say, "Python
> doesn't have variables."   Why can't we say, "Python's variables work
> differently than other languages"?

Apologies, Ned. I didn't mean to make your teeth sore :-)

I've found that when people refer to "variables" they pretty much
inevitably have a picture in their mind of a named box that "contains"
a value (or pointer to a value). They find it difficult to understand
that Python doesn't have those boxes but rather names the values
directly. Sort of. And yes, that 's very much "sort of". It's
certainly just as viable to say to people that Python's idea of
variables is different than (say) C's, but in my experience you end up
qualifying so much that it's easier to use a different term without
the connotations. Sort of like saying "I like apples - the orange ones
that are a type of citrus fruit" :-)

In common usage I'll happily use the terms "variable" and "name"
somewhat interchangeably, but when things degenerate into detail-level
picking over specifics, I avoid doing so. I was wrong to casually say
"Python doesn't have variables", though - if I want to be detailed and
specific, I should make sure my writing reflects that that's what I'm
doing.

I'm curious - How would you explain Python's "variables" to someone
who knows how C variables work, in a way that ensures they don't carry
across any unfortunate misconceptions based on how C works? If I had a
good way of doing that, maybe I wouldn't need to play apple/orange
games when discussing the subject.

Paul
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Are the critiques in "All the things I hate about Python" valid?

2018-02-19 Thread Chris Angelico
On Tue, Feb 20, 2018 at 12:34 AM, Steven D'Aprano
 wrote:
> On Mon, 19 Feb 2018 20:14:32 +1100, Chris Angelico wrote:
>
>> As an integer, 3.141590 is 107853 $
>>
>> Looks to me like C is perfectly happy to interpret a float as an int.
>
> Yes, but that's not an *automatic* coercion. To count as weakly typed,
> the compiler has to do it automatically, without an explicit cast or
> conversion.

Fair enough. If you ignore warnings, then C does have that kind of weak typing:

$ cat demo.c
#include 

int main() {
float f = 3.14159;
int *i = 
printf("As an integer, %f is %d\n", f, *i);
return 0;
}

$ gcc demo.c
demo.c: In function ‘main’:
demo.c:5:14: warning: initialization from incompatible pointer type
[-Wincompatible-pointer-types]
 int *i = 
  ^
$

GCC was quite happy to compile that code, even though the type of ""
is "pointer to float", and it's being assigned to a variable of type
"pointer to int". But C is a language saddled with so much history and
backward compatibility constraints that there are some things you just
CAN'T make into errors; so in terms of "how safe is C?", I'd have to
say that warnings (especially those that are enabled by default - I
didn't need to say "-Wall" for this test), count as "disallowing",
especially if all the major compilers emit warnings on the same code.
But I do see the argument that "it compiles, so the language clearly
permits it".

ChrisA
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Are the critiques in "All the things I hate about Python" valid?

2018-02-19 Thread Anders Wegge Keller
På Mon, 19 Feb 2018 15:15:19 + (UTC)
Steven D'Aprano  skrev:
> On Mon, 19 Feb 2018 14:06:36 +0100, Anders Wegge Keller wrote:
> 
> > Array is not even close to providing a strongly typed container.  
> 
> That's a mighty powerful claim that goes against the documentation for 
> the array module. Can you back your claims up?
> 
> Here's an array and a list:

 Make me an array of tuples with two integers and a string, and we can talk.

-- 
//Wegge
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Are the critiques in "All the things I hate about Python" valid?

2018-02-19 Thread Marko Rauhamaa
Ned Batchelder :
> I guess I'll have to continue to grit my teeth as people say, "Python
> doesn't have variables."   Why can't we say, "Python's variables work
> differently than other languages"?

Because they don't?


Marko
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Are the critiques in "All the things I hate about Python" valid?

2018-02-19 Thread Ned Batchelder

On 2/19/18 9:54 AM, Steven D'Aprano wrote:

On Mon, 19 Feb 2018 13:28:26 +, Paul Moore wrote:


[1] The most basic question, which people making such claims often can't
answer, is "Do you mean that values are strongly typed, or that names
are? Or did you mean that variables are, because if so Python doesn't
even have variables in the sense that you mean" Programming language
semantics are complex.

An excellent point.

The distinction between typing *values* and *names* is a good one.





I guess I'll have to continue to grit my teeth as people say, "Python 
doesn't have variables."   Why can't we say, "Python's variables work 
differently than other languages"?


--Ned.
--
https://mail.python.org/mailman/listinfo/python-list


Re: Are the critiques in "All the things I hate about Python" valid?

2018-02-19 Thread Steven D'Aprano
On Mon, 19 Feb 2018 14:06:36 +0100, Anders Wegge Keller wrote:

> Array is not even close to providing a strongly typed container.

That's a mighty powerful claim that goes against the documentation for 
the array module. Can you back your claims up?

Here's an array and a list:

import array
arr = array.array('I')
lst = []


Without cheating (more on this below), your challenge is to do *any* of 
the following (your choice):

1. Change the type of the object currently assigned to arr to 
   a string (or any other non-array type of your choice); OR

2. Change the type of the object currently assigned to lst to
   a string (or any other non-list type of your choice); OR

3. Assign a string (or any other non-integer value of your 
   choice) to any position in the array; OR

4. Assign a negative integer to any position in the array.

If you can do any of those things (with the restrictions given below), 
I'll happily acknowledge that I was wrong, you were right, and Python's 
"strong typing" is much weaker than I thought (or even non-existent).

On the other hand, if you can't do any of them, I expect you to 
acknowledge that you were wrong.


Here are the restrictions ("no cheating"):

- You can't replace, shadow, monkey-patch or otherwise modify 
  the array module or the array.array type.

- Assigning a new object to the variable name "arr" does not 
  count as changing the type of the existing array object. You
  must change the type of the instance, not replace it with
  another instance.

- Likewise for the lst variable name. You must change the type
  of the object, not re-assign a new object to the same name.

- Any sort of hack involving ctypes is interesting, but doesn't
  count; we know that ctypes can break all sorts of invariants
  by manipulating the C engine. Only standard Python code is
  permitted.

- Likewise you aren't allowed to patch the interpreter. It must
  be the standard CPython interpreter, version 2.4 or greater.

- Nor are you allowed to "cheat" by redefining builtins like 
  print, repr, type, id, sys.displayhook, sys.stdout etc in
  order to fake output.

- Exploiting bugs in the interpreter to cause side-effects 
  don't count (its a bug, not a language feature).

- Any other clever trick that goes against the spirit of the
  requirements will be interesting to see, but not count as
  a success.


The spirit of the requirements are that you demonstrate the ability to do 
something like this:

old_lst = lst  # get a second reference to the list object
assert type(lst) is type([])
do_stuff(lst)  # do something clever to the list object...
assert type(lst) is not type([])  # OMG you changed the type!
assert old_lst is lst  # still the same object

(Similar for arr.)

I don't believe that you can do this. I believe that you have failed to 
understand what we're talking about when we say Python has strong, 
dynamic typing, but I'll be happy for you to prove me wrong.



-- 
Steve

-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Are the critiques in "All the things I hate about Python" valid?

2018-02-19 Thread Steven D'Aprano
On Mon, 19 Feb 2018 13:28:26 +, Paul Moore wrote:

> [1] The most basic question, which people making such claims often can't
> answer, is "Do you mean that values are strongly typed, or that names
> are? Or did you mean that variables are, because if so Python doesn't
> even have variables in the sense that you mean" Programming language
> semantics are complex.

An excellent point.

The distinction between typing *values* and *names* is a good one.



-- 
Steve

-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Are the critiques in "All the things I hate about Python" valid?

2018-02-19 Thread Steven D'Aprano
On Mon, 19 Feb 2018 12:35:19 +, bartc wrote:

> Type systems get rapidly very complicated when you have to deal with
> arbitrary sets of values and with arbitrary rules of interaction.
> Someone has to devise a programming language to allow all that without
> tying itself up in knots. Someone else has to program in it. And someone
> else has to try and understand it!

Indeed. That's exactly the point I'm making.

A type-system that allowed you to express extremely fine-grained 
distinctions would be effectively a fully fledged programming language 
itself, probably even Turing Complete, and so our type-specifications 
would be as error-prone as the code we write now.

Probably more so, due to the requirements that type specifications be a 
lot more compact than the rest of the code we write.


> Ones like C++ has already tied itself itself up in knots just doing the
> basics; I'm not sure how it would handle even my 1,3,5,7,9 type.
> 
> But Python has classes and can do some of this stuff; how would it
> handle a numeric type that is constrained to be whole numbers within
> 0..9 inclusive?

This becomes easy at run-time:

class Digit(int):
def __new__(cls, arg):
instance = super().__new__(cls, arg)
if not 0 <= instance <= 9:
raise ValueError('argument is out of range')
return instance

The above is obviously not a full-blown production-ready class. But it 
illustrates the basic concept. This is the sort of thing that dynamic 
languages excel at: enforcing constraints at run-time which are hard to 
enforce at compile-time.


-- 
Steve

-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Are the critiques in "All the things I hate about Python" valid?

2018-02-19 Thread Steven D'Aprano
On Mon, 19 Feb 2018 12:19:14 +0100, Alain Ketterlin wrote:

> Steven D'Aprano  writes:
> 
>> On Mon, 19 Feb 2018 09:40:09 +0100, Alain Ketterlin wrote:
>>
>>> Tim Delaney  writes:
>>> 
>>> [...]
 As others have said, typing is about how the underlying memory is
 treated.
>>> 
>>> No. It is much more than that. Typing is about everything you can say
>>> about a given statement.
>>
>> "Everything"? Truly *everything*?
> 
> Everything you can say.
> 
>> Given:
>>
>> # engage the type system somehow...
>> # declare a, b, c: non-negative integers 
>> a = abs(int(input("Give me an integer"))) 
>> b = a*a
>> c = (a+1)*(a+1)
>>
>> can you give me an example of a type-system which is capable of telling
>> me that:
>>
>> if (c - b) % 2 == 1:
>> print("hello world")
>> else:
>> fire_missiles()
>>
>> will never fire the missiles?
> 
> Your example is ridiculously simple for all theorem provers I know (not
> on Python code of course, since you can't even be sure int() etc. have
> not been redefined).

I didn't ask about theorem provers. I asked about type systems.

https://en.wikipedia.org/wiki/Automated_theorem_prover

One could, in principle, add a theorem prover to a type system, or at 
least add certain theorem-proving-like functionality to it, but at what 
point does the type checker become complex enough that we can no longer 
trust it? If you don't understand the proof that code is bug-free, you're 
really trusting that the type-checker is bug-free.


> Here is one that makes your point much better:
> 
> if a**n + b**n == c**n:
> print("hello world")
> else:
> fire_missiles()

Either way, I doubt any existing type systems could eliminate the dead 
code in those examples. If you know of one which would, I'd be interested 
to hear about it.


>> I'd be impressed enough with a type system that knew that a%2 was
>> always 0 or 1, although I suppose there could be some that already know
>> that.
>>
>> Hell, I'd even be impressed if it could tell that c was not zero...
> 
> Your claim essentially is: since we cannot prove everything, let's not
> even try to prove anything. Go on if you think this is the right way to
> think about typing.

That's not what I am saying. You're putting words into my mouth and 
criticising me for a position much more extreme than I've expressed.

If you search the archives to this list, you'll see that I've frequently 
supported Python adding type-hints to the language[1], to allow tools 
like MyPy and various linters to perform static analysis on Python code. 
Especially for large projects, that can be helpful.

Type-checking is yet another tool for gathering evidence (not "proving") 
that a program is correct, together with (among others) code review and 
especially testing.

As Donald Knuth said:

"Beware of bugs in the above code; I have only proved it correct, not 
tried it."

What I object to is the idea that static type-checking is "indispensable" 
or sufficient. Its one tool out of many, and more dispensable than some 
of the others.

Even in a big project, which would you rather give up: all testing, or 
all static type checking?

I don't just mean all formal tests, but even running the code to see if 
it works. Literally "it compiles, ship it!". No, I don't think so.

Testing is truly indispensable, whether they are formal tests or not. 
Static typing and "type-safety", not so much.





[1] If you search far back enough, you may find me taking a more extreme 
position that static typing was unnecessary. That was a much younger and 
more naive me.



-- 
Steve

-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Are the critiques in "All the things I hate about Python" valid?

2018-02-19 Thread Steven D'Aprano
On Mon, 19 Feb 2018 20:14:32 +1100, Chris Angelico wrote:

> As an integer, 3.141590 is 107853 $
> 
> Looks to me like C is perfectly happy to interpret a float as an int.

Yes, but that's not an *automatic* coercion. To count as weakly typed, 
the compiler has to do it automatically, without an explicit cast or 
conversion.

I understand well that many people criticise C for making it too easy for 
the programmer to violate type-safety (or even for allowing it *at all*), 
but that's an orthogonal issue -- and probably essential for a systems 
language. D, Rust and other new-generation systems languages which have 
much stronger type systems than C nevertheless also allow programmers to 
escape from the type system when necessary.




-- 
Steve

-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Are the critiques in "All the things I hate about Python" valid?

2018-02-19 Thread Paul Moore
On 19 February 2018 at 13:06, Anders Wegge Keller  wrote:
>  Python isn't particular strong typed. In fact, apart from asking an object
> what type it is, types are not that important. It's the interface that
> matters. I wonder why this is a sore point for Python developers?

Because there's a long history of people claiming that "strongly
typed" languages are fundamentally better than "scripting languages"
(and putting Python in the "scripting language" class) without either
being clear about what "strongly typed" means, or about whether Python
is actually strongly typed or not[1], maybe?

The reality is that the term "strongly typed" can be made to mean
whatever you want it to mean in these debates, and such claims usually
turn out to be little more than statements "yah boo my language is
better than yours and your language sucks".

Paul

[1] The most basic question, which people making such claims often
can't answer, is "Do you mean that values are strongly typed, or that
names are? Or did you mean that variables are, because if so Python
doesn't even have variables in the sense that you mean" Programming
language semantics are complex.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Are the critiques in "All the things I hate about Python" valid?

2018-02-19 Thread Anders Wegge Keller
På Mon, 19 Feb 2018 04:39:31 + (UTC)
Steven D'Aprano  skrev:
> On Mon, 19 Feb 2018 04:26:32 +0100, Anders Wegge Keller wrote:
> 
> > På Mon, 19 Feb 2018 08:47:14 +1100
> > Tim Delaney  skrev:  
> >> On 18 February 2018 at 22:55, Anders Wegge Keller 
> >> wrote:  
> > 
> >   
>  [...]  
> >   
> >> You couldn't have got the above much more wrong.  
> >
> >> As others have said, typing is about how the underlying memory is
> >> treated.  
> > 
> >  And that is exactly my point. Python does not have a typed list. It
> >  have a list that takes whatever is thrown into it.
> > 
> >  I'll skip the rest, as you totally missed the point.  
> 
> I think its actually you have totally missed the point. What you want is 
> a homogeneous list, a list which only accepts items of the same type. The 
> built-in list is not that data structure, but Python already has 
> something similar: see the array module.

 Given that I'm the one making a point about the unwarranted smugness, I
know that I'm not missing anything. Array is not even close to providing a
strongly typed container. For all of the yakking about other languages
weak, blah, BCPL, blah, I still wonder where that need to feel superior to
anything else comes from.  

 Python isn't particular strong typed. In fact, apart from asking an object
what type it is, types are not that important. It's the interface that
matters. I wonder why this is a sore point for Python developers?


-- 
//Wegge
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Are the critiques in "All the things I hate about Python" valid?

2018-02-19 Thread bartc

On 19/02/2018 02:59, Chris Angelico wrote:

On Mon, Feb 19, 2018 at 1:14 PM, bartc  wrote:



How would even a type for the odd numbers from 1 to 10 inclusive work?
(That, a type consisting of one of the values in {1,3,5,7,9}.) Would they be
ordered or unordered? Can I do arithmetic with them: will 3*3 work, but not
3*5?


The type is "positive odd number below ten" and could be written as
int(1..9|1%2). That is an orderable type; you can say that 3 < 7, for
instance. And yes, arithmetic would be defined just fine;


Sometimes, the reason for creating a special numerical type is precisely 
so you can't do arithmetic on them, if it's not meaningful for the type.


So the special type of the values 65..90 might not allow the type be 
multiplied or divided, or added to itself. Because they represent 
characters A..Z. Or house numbers. Or the age of pensioners. (You'd need 
to convert to ordinary integers, is that is allowed.)


 there's no

requirement for the result of an operation to have the same type as
its inputs:





5 / 2 # two integers

2.5


Try that when the type of {1..13} represents playing card ordinal values.

Type systems get rapidly very complicated when you have to deal with 
arbitrary sets of values and with arbitrary rules of interaction. 
Someone has to devise a programming language to allow all that without 
tying itself up in knots. Someone else has to program in it. And someone 
else has to try and understand it!


Ones like C++ has already tied itself itself up in knots just doing the 
basics; I'm not sure how it would handle even my 1,3,5,7,9 type.


But Python has classes and can do some of this stuff; how would it 
handle a numeric type that is constrained to be whole numbers within 
0..9 inclusive?


--
bartc
--
https://mail.python.org/mailman/listinfo/python-list


Re: Are the critiques in "All the things I hate about Python" valid?

2018-02-19 Thread Marko Rauhamaa
Alain Ketterlin :
> Your claim essentially is: since we cannot prove everything, let's not
> even try to prove anything. Go on if you think this is the right way to
> think about typing.

This discussion is far too metaphysical.

Static type declarations give you something at a cost. They give you:

 * Performance (by several orders of magnitude).

 * Static type checking (-> better quality).

They cost:

 * More code to type (-> worse quality, lower productivity).


In my experience it is far easier to produce correct code in Python than
in, say, C++ or Java.

Back to metaphysics: OO has spent far too much energy in ontology. You
shouldn't judge an object based on the class it belongs to.


Marko
-- 
https://mail.python.org/mailman/listinfo/python-list


[OT] multicore/cpu history Re: Are the critiques in "All the things I hate about Python" valid?

2018-02-19 Thread Adriaan Renting



Adriaan Renting| Email: rent...@astron.nl
Software Engineer Radio Observatory
ASTRON | Phone: +31 521 595 100 (797 direct)
P.O. Box 2 | GSM:   +31 6 24 25 17 28
NL-7990 AA Dwingeloo   | FAX:   +31 521 595 101
The Netherlands| Web: http://www.astron.nl/~renting/



>>> On 17-2-2018 at 22:02, in message
,
Chris
Angelico  wrote: 
> On Sun, Feb 18, 2018 at 5:05 AM, Steven D'Aprano
>  wrote:
>> On Sat, 17 Feb 2018 15:25:15 +1100, Chris Angelico wrote:
>>

...

>>> Totally not true. The GIL does not stop other threads from
running.
>>> Also, Python has existed for multiple CPU systems pretty much since
its
>>> inception, I believe. (Summoning the D'Aprano for history lesson?)
>>
>> If you're talking about common desktop computers, I think you're
>> forgetting how recent multicore machines actually are. I'm having
>> difficulty finding when multicore machines first hit the market, but
it
>> seems to have been well into the 21st century -- perhaps as late as
2006
>> with the AMD Athelon 64 X2:
> 
> No, I'm talking about big iron. Has Python been running on multi-CPU
> supercomputers earlier than that?
> 
>> By the way, multiple CPU machines are different from CPUs with
multiple
>> cores:
>>
>> http://smallbusiness.chron.com/multiple-cpu-vs-multicore-33195.html
> 
> Yeah, it was always "multiple CPUs", not "multiple cores" when I was
> growing up. And it was only ever in reference to the expensive
> hardware that I could never even dream of working with. I was always
> on the single-CPU home-grade systems.
> 

Multicore became a thing with the Pentium 4 hyperthreading around ~2002
for consumers, and
multi cpu was a thing much longer, even with "consumer grade"
hardware:

I remember running 2 Mendocino 300 MHz Celerons on a Pentium II Xeon
motherboard to get a
multi-cpu machine for running multiple virtual machines for testing
purposes around 1998.
This was not as Intel intended, but a quite cheap consumer grade
hardware solution.

...
> 
> ChrisA

-- 
https://mail.python.org/mailman/listinfo/python-list


Re: [OT] multicore/cpu history Re: Are the critiques in "All the things I hate about Python" valid?

2018-02-19 Thread Chris Angelico
On Mon, Feb 19, 2018 at 10:39 PM, Adriaan Renting  wrote:
> I remember running 2 Mendocino 300 MHz Celerons on a Pentium II Xeon
> motherboard to get a
> multi-cpu machine for running multiple virtual machines for testing
> purposes around 1998.
> This was not as Intel intended, but a quite cheap consumer grade
> hardware solution.
>

Thanks! That's the sort of thing I was looking for. Out of curiosity,
what was the purpose of that rig and its dual CPUs? Were you running
the host system on one CPU and the guest on another?

ChrisA
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Are the critiques in "All the things I hate about Python" valid?

2018-02-19 Thread Alain Ketterlin
Steven D'Aprano  writes:

> On Mon, 19 Feb 2018 09:40:09 +0100, Alain Ketterlin wrote:
>
>> Tim Delaney  writes:
>> 
>> [...]
>>> As others have said, typing is about how the underlying memory is
>>> treated.
>> 
>> No. It is much more than that. Typing is about everything you can say
>> about a given statement.
>
> "Everything"? Truly *everything*?

Everything you can say.

> Given:
>
> # engage the type system somehow...
> # declare a, b, c: non-negative integers
> a = abs(int(input("Give me an integer")))
> b = a*a
> c = (a+1)*(a+1)
>
> can you give me an example of a type-system which is capable of telling 
> me that:
>
> if (c - b) % 2 == 1:
> print("hello world")
> else:
> fire_missiles()
>
> will never fire the missiles?

Your example is ridiculously simple for all theorem provers I know (not
on Python code of course, since you can't even be sure int() etc. have
not been redefined).

Here is one that makes your point much better:

if a**n + b**n == c**n:
print("hello world")
else:
fire_missiles()

> I'd be impressed enough with a type system that knew that a%2 was always 
> 0 or 1, although I suppose there could be some that already know that.
>
> Hell, I'd even be impressed if it could tell that c was not zero...

Your claim essentially is: since we cannot prove everything, let's not
even try to prove anything. Go on if you think this is the right way to
think about typing.

-- Alain.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Are the critiques in "All the things I hate about Python" valid?

2018-02-19 Thread Chris Angelico
On Mon, Feb 19, 2018 at 9:24 PM, Steven D'Aprano
 wrote:
> On Mon, 19 Feb 2018 09:40:09 +0100, Alain Ketterlin wrote:
>
>> Tim Delaney  writes:
>>
>> [...]
>>> As others have said, typing is about how the underlying memory is
>>> treated.
>>
>> No. It is much more than that. Typing is about everything you can say
>> about a given statement.
>
> "Everything"? Truly *everything*?
>
> Given:
>
> # engage the type system somehow...
> # declare a, b, c: non-negative integers
> a = abs(int(input("Give me an integer")))
> b = a*a
> c = (a+1)*(a+1)
>
> can you give me an example of a type-system which is capable of telling
> me that:
>
> if (c - b) % 2 == 1:
> print("hello world")
> else:
> fire_missiles()
>
> will never fire the missiles?
>
> I'd be impressed enough with a type system that knew that a%2 was always
> 0 or 1, although I suppose there could be some that already know that.
>
> Hell, I'd even be impressed if it could tell that c was not zero...
>

A type system, per se? I don't think so. But static analysis CAN
figure out that sort of thing (obviously, since we as humans can do
it), and I wouldn't be surprised in the least if tools like Coverity
could detect this.

ChrisA
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Are the critiques in "All the things I hate about Python" valid?

2018-02-19 Thread Alain Ketterlin
Chris Angelico  writes:

> On Mon, Feb 19, 2018 at 9:04 PM, Alain Ketterlin
>  wrote:

>> Look at the C11 standard, section 6.3.2.3 ("Pointers"), 6.5.§6-7
>> ("effective types"), and 6.5.3.2 ("Address and indirection operators").
>> It is tiring to constantly correct misunderstandings about pointer
>> casting and dereferencing.
>>
>>> $ cat demo.c; gcc -Wall demo.c; ./a.out
>> [...]
>>
>> If you don't know what undefined behavior is, better avoid C. Your
>> program has UB, anything can happen, including a seemingly sensible
>> result.
>
> Sure it can. But I don't know what you can mean by "stronger rules" if
> all it says is "that's undefined". Saying that behaviour is undefined
> does NOT mean that C has a stronger type system. I got no errors, not
> even a warning in -Wall mode, so there is no indication that my code
> did something wrong.

I used "stronger rules" in response to the OP claim ("C lets you
manipulate memory freely"). Undefined behavior is part of the semantics
of C, the same way infinite loops of signed-integer overflow are. What
compilers can do about it is a different matter. This is well
documented, those that want to ignore UB are on their own. Anyway, I
think it is irrelevant here. Search for "What every programmer should
know about undefined behavior" if you are interested.

-- Alain.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Are the critiques in "All the things I hate about Python" valid?

2018-02-19 Thread Steven D'Aprano
On Mon, 19 Feb 2018 09:40:09 +0100, Alain Ketterlin wrote:

> Tim Delaney  writes:
> 
> [...]
>> As others have said, typing is about how the underlying memory is
>> treated.
> 
> No. It is much more than that. Typing is about everything you can say
> about a given statement.

"Everything"? Truly *everything*?

Given:

# engage the type system somehow...
# declare a, b, c: non-negative integers
a = abs(int(input("Give me an integer")))
b = a*a
c = (a+1)*(a+1)

can you give me an example of a type-system which is capable of telling 
me that:

if (c - b) % 2 == 1:
print("hello world")
else:
fire_missiles()

will never fire the missiles?

I'd be impressed enough with a type system that knew that a%2 was always 
0 or 1, although I suppose there could be some that already know that.

Hell, I'd even be impressed if it could tell that c was not zero...



-- 
Steve

-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Are the critiques in "All the things I hate about Python" valid?

2018-02-19 Thread Chris Angelico
On Mon, Feb 19, 2018 at 9:04 PM, Alain Ketterlin
 wrote:
> Chris Angelico  writes:
>
>> On Mon, Feb 19, 2018 at 7:40 PM, Alain Ketterlin
>>  wrote:
>
>>> No. C has much stronger rules, not on casting, but on accessing the
>>> pointees, which basically invalidates your argument. Refer to the C
>>> standard for details.
>>
>> Really? What rules?
>
> Look at the C11 standard, section 6.3.2.3 ("Pointers"), 6.5.§6-7
> ("effective types"), and 6.5.3.2 ("Address and indirection operators").
> It is tiring to constantly correct misunderstandings about pointer
> casting and dereferencing.
>
>> $ cat demo.c; gcc -Wall demo.c; ./a.out
> [...]
>
> If you don't know what undefined behavior is, better avoid C. Your
> program has UB, anything can happen, including a seemingly sensible
> result.

Sure it can. But I don't know what you can mean by "stronger rules" if
all it says is "that's undefined". Saying that behaviour is undefined
does NOT mean that C has a stronger type system. I got no errors, not
even a warning in -Wall mode, so there is no indication that my code
did something wrong.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Are the critiques in "All the things I hate about Python" valid?

2018-02-19 Thread Chris Angelico
On Mon, Feb 19, 2018 at 8:36 PM, Antoon Pardon  wrote:
> On 17-02-18 21:11, Chris Angelico wrote:
>> On Sun, Feb 18, 2018 at 1:47 AM, Ian Kelly  wrote:
>>> On Fri, Feb 16, 2018 at 9:32 PM, Chris Angelico  wrote:
 You'd be surprised how rarely that kind of performance even matters.
 The author of that article cites C# as a superior language, but in the
 rewrite from C# to Python (the same one I mentioned in the other
 post), I sped the program up incredibly. Part of that is because C#
 requires the startup of its framework (in my case that's Mono) just as
 Python does, and partly it's because the simplicity of Python let me
 eliminate a number of unnecessary HTTP requests. Trust me, your choice
 of language doesn't help you if it means you do three (sequential)
 HTTP requests when one would have done. Clean code has its own
 advantages.
>>> Okay, I'm curious. How did C# force you to make extra HTTP requests
>>> that were no longer necessary when you rewrote in Python?
>> It didn't *force* those requests to be made, but the code was so large
>> and convoluted that I doubt its original author realized that the
>> requests were being repeated. Pseudo-coded:
>
> But was that a reflection on C# or on the original author?
>

A bit of both. It's the language's fault that simple operations take
dozens of lines of code, and the author's fault for not noticing the
redundancies. It's virtually impossible to keep thousands of lines of
code in your head, so the language's lack of good primitives increases
the complexity of the code and thus allows redundancy to lie hidden.

But my main point in the original post was that C# cannot possibly
*help* if most of the time is spent in HTTP requests. I could have
naively transformed the code into Python without seeing any measurable
performance drop, despite Python being "slower" than C#. Makes no
difference what language you write in, if you're waiting on the
network...

ChrisA
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Are the critiques in "All the things I hate about Python" valid?

2018-02-19 Thread Alain Ketterlin
Chris Angelico  writes:

> On Mon, Feb 19, 2018 at 7:40 PM, Alain Ketterlin
>  wrote:

>> No. C has much stronger rules, not on casting, but on accessing the
>> pointees, which basically invalidates your argument. Refer to the C
>> standard for details.
>
> Really? What rules?

Look at the C11 standard, section 6.3.2.3 ("Pointers"), 6.5.§6-7
("effective types"), and 6.5.3.2 ("Address and indirection operators").
It is tiring to constantly correct misunderstandings about pointer
casting and dereferencing.

> $ cat demo.c; gcc -Wall demo.c; ./a.out
[...]

If you don't know what undefined behavior is, better avoid C. Your
program has UB, anything can happen, including a seemingly sensible
result.

>> But you can modify the class (not __class__) in whatever way you want.
>> For instance:
>>
>> class X(object):
>> def f(self): ...
>> ...
>> del X.f
>>
>> So, in Python, knowing that object x is an instance of class X tells
>> you... essentially nothing. Call this strong typing if you want. In
>> terms of type systems, it is (strong) simplistic-typing based on type
>> labels, and labels carry no information whatsoever.
>
> Sure you can. And you can do a lot of other things at run time, too.
> Monkey-patching doesn't change the fact that x really and truly is an
> instance of class X, it just changes what you can do with that object.
> So what you're saying is that Python's dynamism makes it possible to
> disrupt duck typing. Sure, I'll grant you that. But the type system
> itself isn't broken by that.

I didn't say it is broken. I said: it does very little.

-- Alain.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Are the critiques in "All the things I hate about Python" valid?

2018-02-19 Thread Terry Reedy

On 2/19/2018 4:14 AM, Chris Angelico wrote:

On Mon, Feb 19, 2018 at 7:40 PM, Alain Ketterlin
 wrote:

Tim Delaney  writes:

C is statically and weakly typed. Variables know their types at compile
time (static typing). It is a feature of the language that you can cast any
pointer to any chunk of memory to be a pointer to any other type (normally
via void *). This is not coercion - it takes the bit pattern of memory of
one type and interprets it as the bit pattern for another type, and is weak
typing.


No. C has much stronger rules, not on casting, but on accessing the
pointees, which basically invalidates your argument. Refer to the C
standard for details.


Really? What rules?

$ cat demo.c; gcc -Wall demo.c; ./a.out
#include 

int main() {
 float f = 3.14159;
 int *i = (int *)
 printf("As an integer, %f is %d\n", f, *i);
 return 0;
}

As an integer, 3.141590 is 107853
$

Looks to me like C is perfectly happy to interpret a float as an int.
What rules are you seeing violated here?


The last time I tried, C was also willing to ints and arrays thereof as 
an array of chars. (I vaguely remember Fortran doing something like this 
also.  One Fortran int = four chars.)  The C memory model is a linear 
sequence of bytes, each consisting of at least 8 bits.  One means for 
malware attacks it is to disguise and insert binary code bytes as 
character bytes and then trick the CPU into executing the 'characters'.


--
Terry Jan Reedy

--
https://mail.python.org/mailman/listinfo/python-list


Re: Are the critiques in "All the things I hate about Python" valid?

2018-02-19 Thread Antoon Pardon
On 17-02-18 21:11, Chris Angelico wrote:
> On Sun, Feb 18, 2018 at 1:47 AM, Ian Kelly  wrote:
>> On Fri, Feb 16, 2018 at 9:32 PM, Chris Angelico  wrote:
>>> You'd be surprised how rarely that kind of performance even matters.
>>> The author of that article cites C# as a superior language, but in the
>>> rewrite from C# to Python (the same one I mentioned in the other
>>> post), I sped the program up incredibly. Part of that is because C#
>>> requires the startup of its framework (in my case that's Mono) just as
>>> Python does, and partly it's because the simplicity of Python let me
>>> eliminate a number of unnecessary HTTP requests. Trust me, your choice
>>> of language doesn't help you if it means you do three (sequential)
>>> HTTP requests when one would have done. Clean code has its own
>>> advantages.
>> Okay, I'm curious. How did C# force you to make extra HTTP requests
>> that were no longer necessary when you rewrote in Python?
> It didn't *force* those requests to be made, but the code was so large
> and convoluted that I doubt its original author realized that the
> requests were being repeated. Pseudo-coded:

But was that a reflection on C# or on the original author?

-- 
Antoon Pardon


-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Are the critiques in "All the things I hate about Python" valid?

2018-02-19 Thread Chris Angelico
On Mon, Feb 19, 2018 at 7:40 PM, Alain Ketterlin
 wrote:
> Tim Delaney  writes:
>> C is statically and weakly typed. Variables know their types at compile
>> time (static typing). It is a feature of the language that you can cast any
>> pointer to any chunk of memory to be a pointer to any other type (normally
>> via void *). This is not coercion - it takes the bit pattern of memory of
>> one type and interprets it as the bit pattern for another type, and is weak
>> typing.
>
> No. C has much stronger rules, not on casting, but on accessing the
> pointees, which basically invalidates your argument. Refer to the C
> standard for details.

Really? What rules?

$ cat demo.c; gcc -Wall demo.c; ./a.out
#include 

int main() {
float f = 3.14159;
int *i = (int *)
printf("As an integer, %f is %d\n", f, *i);
return 0;
}

As an integer, 3.141590 is 107853
$

Looks to me like C is perfectly happy to interpret a float as an int.
What rules are you seeing violated here?

> But you can modify the class (not __class__) in whatever way you want.
> For instance:
>
> class X(object):
> def f(self): ...
> ...
> del X.f
>
> So, in Python, knowing that object x is an instance of class X tells
> you... essentially nothing. Call this strong typing if you want. In
> terms of type systems, it is (strong) simplistic-typing based on type
> labels, and labels carry no information whatsoever.

Sure you can. And you can do a lot of other things at run time, too.
Monkey-patching doesn't change the fact that x really and truly is an
instance of class X, it just changes what you can do with that object.
So what you're saying is that Python's dynamism makes it possible to
disrupt duck typing. Sure, I'll grant you that. But the type system
itself isn't broken by that.

ChrisA
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Are the critiques in "All the things I hate about Python" valid?

2018-02-19 Thread Alain Ketterlin
Tim Delaney  writes:

[...]
> As others have said, typing is about how the underlying memory is treated.

No. It is much more than that. Typing is about everything you can say
about a given statement. Some type systems are focusing on type labels
only (like most statically typed programming languages), others are
fairly elaborate (for instance, Eiffel's, if requires/ensures are
considered part of the type system). There is a wide range of type
systems, more or less practical depending on your needs (see
https://www.cis.upenn.edu/~bcpierce/tapl/ if you want to see how far you
can go with typing).

[...]
> C is statically and weakly typed. Variables know their types at compile
> time (static typing). It is a feature of the language that you can cast any
> pointer to any chunk of memory to be a pointer to any other type (normally
> via void *). This is not coercion - it takes the bit pattern of memory of
> one type and interprets it as the bit pattern for another type, and is weak
> typing.

No. C has much stronger rules, not on casting, but on accessing the
pointees, which basically invalidates your argument. Refer to the C
standard for details.

> Python is strongly and dynamically typed. In Python, once you create an
> object, it remains that type of object, no matter what you do to it*. That
> makes it strongly typed.
[...]

But you can modify the class (not __class__) in whatever way you want.
For instance:

class X(object):
def f(self): ...
...
del X.f

So, in Python, knowing that object x is an instance of class X tells
you... essentially nothing. Call this strong typing if you want. In
terms of type systems, it is (strong) simplistic-typing based on type
labels, and labels carry no information whatsoever.

Dynamic typing lets you avoid doing nonsense with bit-patterns, as you
say, by gracefully crashing at run-time instead of performing
"unexpected" actions. "Unexpected" is defined by the whole *execution*
of the program up to the point where typing takes place. To understand
whether a Python statement

x.f()

is meaningful (which is what typing is about), you have to know the full
sequence of actions that have taken place on x *and* on its class (and
on everything that that call may use) since the beginning of the
program. For any non-trivial program, this is usually way too complex to
capture, testing will be incomplete, and all you can do is run your
program and see whether is goes through.

As a general rule, if that's all you expect from typing, then, fine,
call this "strong". I won't go as far, and just say that it is good
enough for the programs I use Python for.

-- Alain.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Are the critiques in "All the things I hate about Python" valid?

2018-02-18 Thread Steven D'Aprano
On Mon, 19 Feb 2018 04:26:32 +0100, Anders Wegge Keller wrote:

> På Mon, 19 Feb 2018 08:47:14 +1100
> Tim Delaney  skrev:
>> On 18 February 2018 at 22:55, Anders Wegge Keller 
>> wrote:
> 
> 
>> >  That list is not only weakly typed, but rather untyped. There are no
>> > safeguards in the language, that enforce that all elements in a list
>> > or other container are in fact of the same type. Before type
>> > annotations and mypy, I could not enforce that other than at runtime.
> 
>> You couldn't have got the above much more wrong.
>  
>> As others have said, typing is about how the underlying memory is
>> treated.
> 
>  And that is exactly my point. Python does not have a typed list. It
>  have a list that takes whatever is thrown into it.
> 
>  I'll skip the rest, as you totally missed the point.

I think its actually you have totally missed the point. What you want is 
a homogeneous list, a list which only accepts items of the same type. The 
built-in list is not that data structure, but Python already has 
something similar: see the array module.

If you want a list type which only supports items of a single type, you 
can get one by subclassing.

But that's utterly irrelevant to the question of strong versus weak 
typing. A strongly typed language like Haskell, which does (almost?) no 
automatic coercions at all (possibly not even int to float) can still 
define a "list of Any object" type, just like Python's built-in list.

That doesn't make Haskell untyped, and it is a sign of your confusion 
that you think it makes Python untyped. Sorry to be blunt, but you're not 
even in the right ballpark here.

Python is strongly typed because a list is a list, regardless of its 
contents. If you say "1 + []" Python does not try to cast or convert the 
list into an int and add them, or interpret the int as a list, and 
perform list concatenation on a chunk of memory that is actually an int 
but is being treated as an (almost certainly invalid!) list.

Remember:

- the static/dynamic distinction is between *when* types are checked 
(compile time or run time), not *whether* they are checked;

- untyped languages treat *everything* (or almost everything) as the same 
type: usually either a chunk of raw bits, like in assembly, or text 
strings, like in many shell scripting languages;

- weakly typed languages do a lot of automatic coercions; 

- strongly typed languages do very few or no automatic coercions.


None of those distinctions have anything to say about whether the 
standard library offers a homogeneous list where all the items have the 
same type.



-- 
Steve

-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Are the critiques in "All the things I hate about Python" valid?

2018-02-18 Thread Steven D'Aprano
On Mon, 19 Feb 2018 02:14:26 +, bartc wrote:

> On 19/02/2018 00:09, Steven D'Aprano wrote:
> 
>> Sure, but only the most boring, uninteresting kinds of types can be so
>> named. The point is that "sufficiently fine-grained types" can be
>> arbitrarily complex.
> 
> I don't think so.

That's nice. Do you have any reasons for your position?


>> If a human finds it hard to give it a meaningful
>> name, no algorithm will do it either. Consider:
>> 
>> "positive odd integers greater than 10 but less than 15003 divisible by
>> 17 except for 850, 867 and 1394; or primes that aren't Mersenne
>> primes".
> 
> Is that a type? Or a function? Or a set? Or a constraint?

It *could* be a type, if your type system was sufficiently flexible to 
allow you to specify something in that level of detail. Of course no 
existing type system is.

Which is of course my point: why static typing zealots do like to make 
grandiose claims about "sufficiently fine-grained types", the reality is 
that no type system is, or can be, sufficiently fine-grained to avoid all 
runtime validation.


> How would even a type for the odd numbers from 1 to 10 inclusive work?

That's an easy one: even Pascal in the 1970s could deal with enumerated 
types like the values 1, 3, 5, 7, 9. (I think.) So that's something that 
a type checker could easily verify at compile time. Given:

declare x, y : OddIntBetweenOneAndTen;

then:

x := 3

would be allowed, but:

y := x + 2

probably would be rejected, because the compiler may not be able to tell 
whether or not x + 2 is still an OddIntBetweenOneAndTen (unless it is 
actually tracking the value of x, which type checkers don't normally do).

Of course this put *severe* limitations on what you can do with such 
highly restrictive types, which is also part of my point.


> (That, a type consisting of one of the values in {1,3,5,7,9}.) Would
> they be ordered or unordered? Can I do arithmetic with them: will 3*3
> work, but not 3*5?

Operations on types do not necessarily have to return their same type. 
There's nothing wrong with saying that Odd plus Odd returns Even.



-- 
Steve

-- 
https://mail.python.org/mailman/listinfo/python-list


  1   2   >