Re: What's the best way to minimize the need of run time checks?

2016-08-28 Thread Steven D'Aprano
On Sunday 28 August 2016 15:56, Juan Pablo Romero Méndez wrote:

> 2016-08-27 21:30 GMT-07:00 Steve D'Aprano :
[...]
>> Now it is true that speaking in full generality, classes and types refer to
>> different things. Or to be perhaps more accurate, *subclassing* and
>> *subtyping* are different things:
>>
>> http://c2.com/cgi/wiki?SubTypingAndSubClassing
>>
>> Many languages treat them the same, but fundamentally they are different.
> 
> Oh, I don't think he is thinking in terms of OO "classes", I think he meant
> two different "kinds" or "varieties" of values (although kind has a
> technical meaning)

That's not quite right either. "Two different kinds or varieties" is what both 
subclassing and subtyping aim to describe, in different ways: e.g. dogs and 
cats are two different kinds of mammal.

What you are describing here:

> In TypeScript terms what he is saying can be described like this:
> 
> type Complex =
>  { real: number, i: number }
> | { r: number, φ: number}
> 
> const c1: Complex = { real: 1, i: 1 }
> const c2: Complex = { r: 1, φ: 0.5 }
> 
> You have two values of the same type but different representation.

seems to be more like what is called "variant record" in Pascal.

http://www.freepascal.org/docs-html/ref/refsu16.html


I'm not familiar with TypeScript. How does this work? If I say:

const c1: Complex = {real: 1, imag: 1 }

print c1.r
print c1.φ

what do I get? If r and φ are merely alternative names for "real" and "imag", 
that's not good enough. Given real=1, imag=1, then we need to get r=1.414213 
and φ = pi/4 without any extra effort on the part of the user.


The point is, the complex number (1, 1) in Cartesian coordinates and (sqrt(2), 
pi/4) in polar coordinates aren't two different kinds of things, they are two 
different ways of writing the same value. Like writing 1A in hex and 26 in 
decimal. Somebody may choose to implement this as two different classes 
("CartesianComplex" and "PolarComplex") but that's a limitation of their code, 
or of their language, it doesn't reflect a real difference between two 
different kinds of things.

Another way to put it:

If you were programming a first person shooter game, you might choose each of 
the enemies as an object. Let's say you have an enemy called the Grue. You can 
view the Grue from the front or from the back, depending on which way it is 
standing when you see it. Would you implement this as two different classes?

GrueSeenFromFront

GrueSeenFromBack

I should hope not. It's the same object, the same Grue, it just looks different 
depending on which way you approach it.





-- 
Steve

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


Re: What's the best way to minimize the need of run time checks?

2016-08-28 Thread Jussi Piitulainen
Chris Angelico writes:

> On Sun, Aug 28, 2016 at 4:13 PM, Jussi Piitulainen wrote:
>>> This is where I'm less sure. Sometimes a variable's type should be
>>> broader than just one concrete type - for instance, a variable might
>>> hold 1 over here, and 1.5 over there, and thus is storing either
>>> "int or float" or "any number". If you have a complex hierarchy of
>>> types, how do you know that this variable should be allowed to hold
>>> anything up to a certain level in the hierarchy, and no further?
>>
>> It's not just literal values that give potential type information in
>> a dynamically typed language. Another source is functions that the
>> compiler knows, and this information propagates back and forth in the
>> analysis of the control flow.
>>
>> For example, below the compiler might infer that x must be a number
>> but not a complex number, then generate one type check (which it
>> might be able to prove redundant) and calls to specialized versions
>> of ceiling and floor.
>>
>> d = ceiling(x) - floor(x)
>>
>> Also known is that the results of the calls are numbers and the
>> difference of numbers is a number, so d gets assigned a number.
>> Perhaps ceiling and floor in the language always return an int. Then
>> d is known to be an int. And so on.
>
> Right, and I understand this concept. Consider this code:
>
> x = 5;
> ...
> if (some_condition)
> x = "five";
> else
> x = [0, 0, 0, 0, 0];
>
> (adjust syntax to whatever language you like)
>
> Does this mean that the type of x is int|string|list, or will this be
> an error? Assuming the condition can't be known until run time (eg it
> involves user input), there's no way for a static analyzer to
> differentiate between this code and the form that Steven put forward:

I'm thinking of a dynamically typed language, so the type of x is the
type of a value, so:

Before the conditional, x is known to be 5 (an int).

After the conditional, x is known to be "five" or [0,0,0,0,0] (a string
or a list of int; not an int).

If the next statement is to return -x, *that* is an error, because -x
does not make sense after either branch of the conditional.

It the next statement is to return x.swapcase(), the compiler can
replace the conditional with

   if (some_condition)
  return "FIVE" # assuming local x
   else
  raise Objection("list don't have no .swapcase() method")

In no case would I say that a mere assignment to a variable is a type
error in a dynamically typed language.

>> x = 1
>> x = "hello"  # a type error, at compile time
>
> Simple type inference would either see this as meaning that x is
> int|string, or possibly it'd say "x is an int up to that second line,
> and a string thereafter" (which is basically like dynamic typing but
> statically checked - it's the value, not the variable, that has a
> type, and checks like x.upper() would take note of that). But if it
> flags it as an error, that would basically mean that the type system
> is (probably deliberately) simplistic and restrictive, requiring that
> x be EITHER an integer variable OR a string variable, and not both.

I'd say that the compiler of a dynamically typed language has different
information about the type of (the value of) x after the first statement
and after the second statement.

If that is considered an error instead, as the comment says, then the
language is statically typed (the type pertains to the variable).

> Which is a perfectly viable stance, but I'm just not sure if it's (a)
> what is done, or (b) ideal. Particularly since it'd end up requiring
> some annoying rules, like "integers and floats are compatible, but
> nothing else, including user-defined types" or "integers and floats
> are fundamentally different things, and if you want your variable ever
> to contain a float, you have to always use 1.0 instead of just 1",
> neither of which I like.

I suppose statically typed type-inferencing languages do that, but I
don't have much experience with them. They may not be happy until they
can infer a concrete implementation type for every variable, and there
may be some awkward corners then.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: What's the best way to minimize the need of run time checks?

2016-08-28 Thread Steven D'Aprano
On Sunday 28 August 2016 15:29, Chris Angelico wrote:

> On Sun, Aug 28, 2016 at 2:30 PM, Steve D'Aprano
>  wrote:
>> But the author of this piece ignores that standard distinction and invents
>> his own non-standard one: to him, classes are merely different
>> representations of the same data. E.g. his example of complex numbers,
>> shown as Cartesian (x, y) values or polar (r, θ) values. These aren't two
>> different "kinds of things", but merely two different ways of representing
>> the same entity.
>>
>> That's not a good way to think about (say) Python lists and Python bools.
>> Lists and bools are in no way the same kind of entity (except in the most
>> general category of "they're both objects").
>>
>> It's not even a very good way of thinking about complex numbers.
> 
> It might be a good way of thinking about points on a Cartesian plane,
> though. Rectangular and polar coordinates truly are just different
> ways of expressing the same information. 

That's exactly my point, and that's why you shouldn't implement them as 
different classes. If you do, that's a limitation of your code and/or the 
language.

(There may be *implementation specific* reasons why you are forced to, for 
example to avoid rounding errors due to finite precision: say, my polar number 
(1, 45°) may not evaluate as *exactly* (sqrt(2)/2, sqrt(2)/2) in Cartesian 
coordinates due to rounding. But that's a case of a leaky abstraction.)


> (How well 2D coordinates map
> to complex numbers is a separate question.)

Mathematically speaking, they map together perfectly well. 


[...]
> This is where I'm less sure. Sometimes a variable's type should be
> broader than just one concrete type - for instance, a variable might
> hold 1 over here, and 1.5 over there, and thus is storing either "int
> or float" or "any number". If you have a complex hierarchy of types,
> how do you know that this variable should be allowed to hold anything
> up to a certain level in the hierarchy, and no further?

This depends on the sophistication of the type system and support (or lack of 
support) for polymorphism:

https://en.wikipedia.org/wiki/Polymorphism_%28computer_science%29

Type punning is normally considered a way to subvert or bypass the type system, 
and is normally considered a bad but necessary thing:

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

In general, primitive type systems like that used by Pascal (and C?) don't deal 
well, or at all, with the scenario you describe. Often the built-in functions 
can hard-code support for multiple numeric types, automatically promoting one 
type to another as necessary, but the same effect is almost impossible to 
achieve in (say) standard Pascal.

Other type-checkers can deal better with polymorphism.

But there's a trade-off: the more kinds of things a value or variable might be, 
the less certain you are of what is allowed ahead of time. That's why dynamic 
typed languages traditionally skipped *all* ahead-of-time type checking and 
instead relied entirely on runtime type errors, while traditional compilers 
restrict what you can do as the trade-off for catching more errors ahead of 
time.

(That's where the reputation for flexibility of dynamic typing comes from: you 
never need to fight the compiler to do something you know will be okay, like 
passing an int to a function that expects a float.)

I might be able to tell the compiler that x is Union[int, str] (a number, or a 
string) but that limits the ability of the compiler to tell what is and what 
isn't safe. If I declare that x is either an int or a str, what can we say 
about x.upper()? Is it safe? If x happens to be an int at the time we call 
x.upper(), will the language raise a runtime exception or will it blindly try 
to execute some arbitrary chunk of memory as the upper() method?

This is why static and dynamic typing are slowly converging: statically typed 
languages are slowly gaining dynamic features, like C++ and vtables:

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

while dynamically typed languages are slowly gaining smarter compilers capable 
of doing some "best effort" compile-time type-checking. Or at least allowing 
external type-checkers/linters to do so.

The bottom line is that if a human reader can read the source code and deduce 
that x.upper() is safe because in this branch of the code, x must be a string 
rather than an int, then *in principle* a type-checker could do the same. 
Possibly better than a human, or possibly worse. Depends on the intelligence of 
the type-checker and the code being checked.

A good enough type-checker can find infinite loops:

http://perl.plover.com/yak/typing/notes.html



> If what the compiler's doing is identifying what *is* assigned, then
> it's easy. You've given it an int over here and a float over there,
> and that's legal; from that point on, the compiler knows that this
> contains either an int or a float. (Let's assume it can't know for
> sure which, eg it has "if (cond) x=

Multimeter USB output

2016-08-28 Thread Joe


Am 28.08.2016 um 00:45 schrieb Terry Reedy:
> On 8/27/2016 3:35 PM, Joe wrote:
>> Hi,
>>
>> I'm using Python 3.5.1 with PyUSB 1.0 under Win 10 (64). We try to read
>> the USB output of a DMM 'UT61B'.
>>
>> import usb.core
>> import usb.util
>> import usb.backend.libusb1
>>
>> def Gosub():
>>  dev = usb.core.find(idVendor=0x1a86, idProduct=0xe008) # Digital
>> Multimeter UT61B
>>  if dev == None:
>>  print ('Multimeter not found')
>>  else:
>>  print ('Multimeter was found')
>>  dev.set_configuration()
>>  cfg = dev.get_active_configuration()
>>  intf = cfg[(0,0)]
>>  ep = usb.util.find_descriptor(
>>  intf,
>>  custom_match = \
>>  lambda e: \
>> usb.util.endpoint_direction(e.bEndpointAddress) == \
>> usb.util.ENDPOINT_IN)
>>  if ep == None:
>>  print ('ep is None')
>>  else:
>>  s = ep.read(64, 500)
>>  print ('Len s: ' + len(s))
>>
>> print ('Starting')
>> Gosub()
>> print ('Ready.-')
>>
>> Result:
>
> I presume you saw
> Starting
> Multimeter was found
>
>> File "d:\work-d\PythonProgs\ut61b.py", line 27, in 
>>Gosub()
>> File "d:\work-d\PythonProgs\ut61b.py", line 23, in Gosub
>>s = ep.read(64, 500)
>> File "D:\Python3\Lib\site-packages\usb\core.py", line 402, in read
>>return self.device.read(self, size_or_buffer, timeout)
>> File "D:\Python3\Lib\site-packages\usb\core.py", line 988, in read
>>self.__get_timeout(timeout))
>> File "D:\Python3\Lib\site-packages\usb\backend\libusb1.py", line 851, in
>> intr_read
>>timeout)
>> File "D:\Python3\Lib\site-packages\usb\backend\libusb1.py", line 936, in
>> __read
>>_check(retval)
>> File "D:\Python3\Lib\site-packages\usb\backend\libusb1.py", line 595, in
>> _check
>>raise USBError(_strerror(ret), ret, _libusb_errno[ret])
>>
>> usb.core.USBError: [Errno 10060] Operation timed out
>>
>> What's wrong? How to fix?
>
> Read (again?) the doc for the interface for the device.  Because reading
> timed out, I suspect that it is waiting for a command for it to send
> something.
>

Yes, I saw this:

Starting
Multimeter was found

The UT61B has two interfaces, a RS232C interface and this usb interface. 
The RS232 interface works well with PySerial. It continously transmits 2 
.. 3 Pakets per second with 14 Bytes each. This happens unsolicited 
without any command as long as the RS232C/USB button on the DMM is active.


So I assumed the USB interface also doesn't need any command and also
transmit this stream of 2 to 3 Pakets per second. But unfortunately I 
don't have any doc for the USB interface for this device.


To the accompanying software of the UT61B there is a ready windos app 
which shows and logs the output of the UT61B. This app can be switched 
between RS232C and USB; both work.


I asked the manufacturer (Uni-T in Shenzen) for additional info and are 
now waiting for an answer.


Assumed the USB interface sends this 2 to 3 pakets per second 
unsolicited - should the code shown work? Is this ok:



>>  lambda e: \
>> usb.util.endpoint_direction(e.bEndpointAddress) == \
>> usb.util.ENDPOINT_IN)

I am in doubt: Is usb.util.ENDPOINT_IN really correct?

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


Re: What's the best way to minimize the need of run time checks?

2016-08-28 Thread Chris Angelico
On Sun, Aug 28, 2016 at 6:33 PM, Steven D'Aprano
 wrote:
> On Sunday 28 August 2016 15:29, Chris Angelico wrote:
>> It might be a good way of thinking about points on a Cartesian plane,
>> though. Rectangular and polar coordinates truly are just different
>> ways of expressing the same information.
>
> That's exactly my point, and that's why you shouldn't implement them as
> different classes. If you do, that's a limitation of your code and/or the
> language.
>
> (There may be *implementation specific* reasons why you are forced to, for
> example to avoid rounding errors due to finite precision: say, my polar number
> (1, 45°) may not evaluate as *exactly* (sqrt(2)/2, sqrt(2)/2) in Cartesian
> coordinates due to rounding. But that's a case of a leaky abstraction.)

class Complex(complex):
@property
def r(self):
return abs(self)
@property
def phi(self):
return cmath.phase(self)

One value, two ways of looking at it. One type. One class.

> I might be able to tell the compiler that x is Union[int, str] (a number, or a
> string) but that limits the ability of the compiler to tell what is and what
> isn't safe. If I declare that x is either an int or a str, what can we say
> about x.upper()? Is it safe? If x happens to be an int at the time we call
> x.upper(), will the language raise a runtime exception or will it blindly try
> to execute some arbitrary chunk of memory as the upper() method?

That's fine if you *tell* the compiler this. My question came from
your statement that a type *inference* system can detect errors of
assignment - not method/operator usage. A dynamic type inference
system could easily cope with this:

x = 5
y = x**2
x = "five"
z = x.upper()

and correctly deduce that, at the time of y's assignment,
exponentiation of x was legal, and at the time of z's, uppercasing
was. But you said that the type system could flag the third line as an
error, saying "hey, I'm expecting this to be integers only". Here's
what you said:

> x = 1
> x = "hello"  # a type error, at compile time

If I were doing type inference, with my limited knowledge of the
field, I would do one of two things:

1) Infer that x holds only integers (or maybe broaden it to
"numbers"), and then raise an error on the second line; this basically
restricts the type system to be union-free
2) Infer that x holds Union[int, str] in PEP 484 notation, or
int|string in Pike notation, and permit it to carry either type.

Which way is it? Do you get errors, as per your example, and thus are
never allowed to have union types? And if so, what happens with
compatible types (notably, int and float)? Can user-defined types be
deemed "compatible"? Are the same types always compatible? Or are no
types ever compatible, and you just have a single Number type, like in
ECMAScript?

> Okay. What happens when you say:
>
> if random() < 0.5:
> x = 1234
> else:
> x = "surprise!"
>
> y = 3*(x + 1)
> z = x.find("p")  # or however Pike does string functions/methods
>
>
> What is y? What is z?

In Pike, variables get declared. So we have a few possibilities:

1) Declaration was "int x;" and the else clause is a compile-time error
2) Declaration was "string x;" and the converse
3) Declaration was "int|string x;" or "mixed x;" or some other broad
form, and they are both accepted.

> There are solutions to this conundrum. One is weak typing: 3*("surprise!" + 1)
> evaluates as 3*(0 + 1) or just 3, while (1234).find("p") coerces 1234 to the
> string "1234".
>
> Another is runtime exceptions.

In this example, y would be "surprise!1surprise!1surprise!1", because
Pike allows strings and integers to be added (representing the int
with ASCII decimal digits), but if the expression were 3*(x-1)
instead, then these would be run-time exceptions. Pike, like Python,
strongly types its values, so if the variable declaration doesn't
prevent something illogical from being compiled, it'll throw a nice
tidy exception at you. The find method, being applied to an integer,
would definitely be an exception, more-or-less "integers don't have
such a method, moron".

> A third is "don't do that, if you do, you can deal with the segmentation
> fault".

Only in C, where segfaults are considered a normal part of life. In
high level languages, no thank you.

> A fourth would be that the type-checker is smart enough to recognise that only
> one of those two assignments is valid, the second must be illegal, and flag 
> the
> whole thing. That's what a human would do -- I don't know if any type systems
> are that sophisticated.

Ooh that would be VERY sophisticated. I don't know of anything that
does that, but it could be done on the same basis as the C "undefined
behaviour" thing you so revile against - basically, the compiler says
"well, if the programmer knows what he's doing, x MUST be an integer
at this point, ergo I can assume that it really will be an integer".
I've seen levels of sophistication like that in tools like Coverity
and how it detects

Re: Is duck-typing misnamed?

2016-08-28 Thread Joe

Am 28.08.2016 um 00:34 schrieb Terry Reedy:

On 8/26/2016 7:58 PM, ROGER GRAYDON CHRISTMAN wrote:

"If it walks like a duck, quacks like a duck,... "

so there is indeed precedence for this so-called 'duck typing'


but wouldn't it be more Pythonic to call this 'witch typing'?

"How do you know she is a witch?"

"She looks like one."


Given that people were once burned to death for 'looking like a witch'
(or sounding or acting), and can still suffer socially for such reasons,
this it not funny to me.  We should stick with ducks.


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


Re: Multimeter USB output

2016-08-28 Thread Terry Reedy

On 8/28/2016 5:13 AM, Joe wrote:


Am 28.08.2016 um 00:45 schrieb Terry Reedy:

On 8/27/2016 3:35 PM, Joe wrote:

Hi,

I'm using Python 3.5.1 with PyUSB 1.0 under Win 10 (64). We try to read
the USB output of a DMM 'UT61B'.

import usb.core
import usb.util
import usb.backend.libusb1

def Gosub():
 dev = usb.core.find(idVendor=0x1a86, idProduct=0xe008) # Digital
Multimeter UT61B
 if dev == None:
 print ('Multimeter not found')
 else:
 print ('Multimeter was found')
 dev.set_configuration()
 cfg = dev.get_active_configuration()
 intf = cfg[(0,0)]
 ep = usb.util.find_descriptor(
 intf,
 custom_match = \
 lambda e: \
usb.util.endpoint_direction(e.bEndpointAddress) == \
usb.util.ENDPOINT_IN)
 if ep == None:
 print ('ep is None')
 else:
 s = ep.read(64, 500)
 print ('Len s: ' + len(s))

print ('Starting')
Gosub()
print ('Ready.-')

Result:


I presume you saw
Starting
Multimeter was found


File "d:\work-d\PythonProgs\ut61b.py", line 27, in 
   Gosub()
File "d:\work-d\PythonProgs\ut61b.py", line 23, in Gosub
   s = ep.read(64, 500)
File "D:\Python3\Lib\site-packages\usb\core.py", line 402, in read
   return self.device.read(self, size_or_buffer, timeout)
File "D:\Python3\Lib\site-packages\usb\core.py", line 988, in read
   self.__get_timeout(timeout))
File "D:\Python3\Lib\site-packages\usb\backend\libusb1.py", line 851, in
intr_read
   timeout)
File "D:\Python3\Lib\site-packages\usb\backend\libusb1.py", line 936, in
__read
   _check(retval)
File "D:\Python3\Lib\site-packages\usb\backend\libusb1.py", line 595, in
_check
   raise USBError(_strerror(ret), ret, _libusb_errno[ret])

usb.core.USBError: [Errno 10060] Operation timed out

What's wrong? How to fix?


Read (again?) the doc for the interface for the device.  Because reading
timed out, I suspect that it is waiting for a command for it to send
something.



Yes, I saw this:

Starting
Multimeter was found

The UT61B has two interfaces, a RS232C interface and this usb interface.
The RS232 interface works well with PySerial. It continously transmits 2
.. 3 Pakets per second with 14 Bytes each. This happens unsolicited
without any command as long as the RS232C/USB button on the DMM is active.

So I assumed the USB interface also doesn't need any command and also
transmit this stream of 2 to 3 Pakets per second. But unfortunately I
don't have any doc for the USB interface for this device.

To the accompanying software of the UT61B there is a ready windos app
which shows and logs the output of the UT61B. This app can be switched
between RS232C and USB; both work.

I asked the manufacturer (Uni-T in Shenzen) for additional info and are
now waiting for an answer.

Assumed the USB interface sends this 2 to 3 pakets per second
unsolicited - should the code shown work? Is this ok:



 lambda e: \
usb.util.endpoint_direction(e.bEndpointAddress) == \
usb.util.ENDPOINT_IN)


I am in doubt: Is usb.util.ENDPOINT_IN really correct?


I do not know as I have not used the usb package.

--
Terry Jan Reedy

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


Re: What's the best way to minimize the need of run time checks?

2016-08-28 Thread Juan Pablo Romero Méndez
2016-08-28 0:04 GMT-07:00 Steven D'Aprano <
steve+comp.lang.pyt...@pearwood.info>:

> On Sunday 28 August 2016 15:56, Juan Pablo Romero Méndez wrote:
>
> > 2016-08-27 21:30 GMT-07:00 Steve D'Aprano :
> [...]
> >> Now it is true that speaking in full generality, classes and types
> refer to
> >> different things. Or to be perhaps more accurate, *subclassing* and
> >> *subtyping* are different things:
> >>
> >> http://c2.com/cgi/wiki?SubTypingAndSubClassing
> >>
> >> Many languages treat them the same, but fundamentally they are
> different.
> >
> > Oh, I don't think he is thinking in terms of OO "classes", I think he
> meant
> > two different "kinds" or "varieties" of values (although kind has a
> > technical meaning)
>
> That's not quite right either. "Two different kinds or varieties" is what
> both
> subclassing and subtyping aim to describe, in different ways: e.g. dogs and
> cats are two different kinds of mammal.
>
> What you are describing here:
>
> > In TypeScript terms what he is saying can be described like this:
> >
> > type Complex =
> >  { real: number, i: number }
> > | { r: number, φ: number}
> >
> > const c1: Complex = { real: 1, i: 1 }
> > const c2: Complex = { r: 1, φ: 0.5 }
> >
> > You have two values of the same type but different representation.
>
> seems to be more like what is called "variant record" in Pascal.
>
> http://www.freepascal.org/docs-html/ref/refsu16.html
>
>
> I'm not familiar with TypeScript. How does this work? If I say:
>
> const c1: Complex = {real: 1, imag: 1 }
>
> print c1.r
> print c1.φ
>
> what do I get? If r and φ are merely alternative names for "real" and
> "imag",
> that's not good enough. Given real=1, imag=1, then we need to get
> r=1.414213
> and φ = pi/4 without any extra effort on the part of the user.
>
>

Here's a more complete example:

type CartesianC = { real: number, i: number }
type PolarC = { r: number, φ: number}

type Complex = PolarC | CartesianC

const c1: Complex = { real: 1, i: 1 };
const c2: Complex = { r: 1, φ: 0.5 };

// This is called a Type Guard

function isCartesian(c: Complex): c is CartesianC {

return ( c).real !== undefined;
}

if(isCartesian(c1)) {
// c1 is a CartesianC here
c1.real
} else {
// and a PolarC here. Using c1.real is a compile error
c1.r
}

TypeScript doesn't support pattern matching so there's some boilerplate
involved: you need to define a TypeGuard so that inside the if branch TS
allows you to treat c1 as a CartesianC; within the else branch it is
treated as a PolarC.



>
> The point is, the complex number (1, 1) in Cartesian coordinates and
> (sqrt(2),
> pi/4) in polar coordinates aren't two different kinds of things, they are
> two
> different ways of writing the same value. Like writing 1A in hex and 26 in
> decimal. Somebody may choose to implement this as two different classes
> ("CartesianComplex" and "PolarComplex") but that's a limitation of their
> code,
> or of their language, it doesn't reflect a real difference between two
> different kinds of things.
>


Well conceptually you might think of c1 as the abstract representation of a
complex number but at runtime they have very different constitutions.



>
> Another way to put it:
>
> If you were programming a first person shooter game, you might choose each
> of
> the enemies as an object. Let's say you have an enemy called the Grue. You
> can
> view the Grue from the front or from the back, depending on which way it is
> standing when you see it. Would you implement this as two different
> classes?
>
> GrueSeenFromFront
>
> GrueSeenFromBack
>
> I should hope not. It's the same object, the same Grue, it just looks
> different
> depending on which way you approach it.
>
>
>
>
>
> --
> Steve
>
> --
> https://mail.python.org/mailman/listinfo/python-list
>
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Is duck-typing misnamed?

2016-08-28 Thread Eric S. Johansson


On 8/27/2016 7:28 PM, ROGER GRAYDON CHRISTMAN wrote:
> Your response is appreciated.   I just thought I'd comment a little more on 
> the
> script:
>
> Woman:  I'm not a witch! I'm not a witch!
>
> V:  ehh... but you are dressed like one.
>
> W:  They dressed me up like this!
>
> All: naah  no we didn't... no.
>
> W:  And this isn't my nose, it's a false one.
>
> (V lifts up carrot)
>
> V: Well?
>
> P1:  Well we did do the nose
>
> V: The nose?
>
> P1:  ...And the hat, but she is a witch!
>
>
> They took a woman who originally, I think we might agree, was not a witch,
> and they added features that were understood to be part of the protocol
> for witchiness.

not a witch??

https://www.youtube.com/watch?v=zrzMhU_4m-g

start at 3:30

listen to what she says after they discover she weights as much as a duck.


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


Re: Is duck-typing misnamed?

2016-08-28 Thread Michael Torrie
On 08/27/2016 05:28 PM, ROGER GRAYDON CHRISTMAN wrote:
> They took a woman who originally, I think we might agree, was not a witch,

Umm no, she was actually a witch.  Which makes the scene even funnier.
"Fair caught," she says at the end.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: What's the best way to minimize the need of run time checks?

2016-08-28 Thread Steve D'Aprano
On Sun, 28 Aug 2016 07:28 pm, Chris Angelico wrote:

> On Sun, Aug 28, 2016 at 6:33 PM, Steven D'Aprano
>  wrote:
>> On Sunday 28 August 2016 15:29, Chris Angelico wrote:
>>> It might be a good way of thinking about points on a Cartesian plane,
>>> though. Rectangular and polar coordinates truly are just different
>>> ways of expressing the same information.
>>
>> That's exactly my point, and that's why you shouldn't implement them as
>> different classes. If you do, that's a limitation of your code and/or the
>> language.
[... snip digression over possible leaky abstractions due to floating point
rounding ...]

> class Complex(complex):
> @property
> def r(self):
> return abs(self)
> @property
> def phi(self):
> return cmath.phase(self)
> 
> One value, two ways of looking at it. One type. One class.

I can't tell if you're saying this to agree with me or to disagree with me.



>> I might be able to tell the compiler that x is Union[int, str] (a number,
>> or a string) but that limits the ability of the compiler to tell what is
>> and what isn't safe. If I declare that x is either an int or a str, what
>> can we say about x.upper()? Is it safe? If x happens to be an int at the
>> time we call x.upper(), will the language raise a runtime exception or
>> will it blindly try to execute some arbitrary chunk of memory as the
>> upper() method?
> 
> That's fine if you *tell* the compiler this.

I trust you don't actually mean that it is fine for a high-level
(non-assembly) language to blindly execute some arbitrary memory address.


> My question came from 
> your statement that a type *inference* system can detect errors of
> assignment - not method/operator usage.

Ignore the question of inference versus declaration. At least for simple
cases, there's no real difference between the C-like declaration and
assignment:

int x = 5;

and the assignment:

x = 5;

It doesn't require super-human, or even human, intelligence to infer that if
x is assigned the value 5, x must be an int. So a *simple* inference engine
isn't very sophisticated.

Your question seems to be, what happens if you follow that with an
assignment to a different type?

x = 5
some_code(x)
x = "hello world"


Will the type-checker consider that an error ("you're assigning a str to an
int") or will it infer that x is the Union[int, str]?

Surely that depends on the type-checker! I don't think there's any hard and
fast rule about that, but as far as I know, all statically typed languages
consider than an error. Remember, that's the definition of *static typing*:
the variable carries the type, not the value. So x is an int, and "hello
world" isn't an int, so this MUST be an error.

In dynamically typed languages... I don't know. I think that (again) I would
expect that *by default* the checker should treat this as an invalid
assignment. The whole point of a static type-checker is to bring some
simulacrum of static typing to a dynamic language, so if you're going to
enthusiastically infer union types every time you see an unexpected type
assignment, it sort of defeats the purpose...

"x was declared int, and you then call function foo() which is declared to
return an int, but sometimes returns a str... oh, they must have meant a
union, so that's okay..."


> A dynamic type inference 
> system could easily cope with this:
> 
> x = 5
> y = x**2
> x = "five"
> z = x.upper()
> 
> and correctly deduce that, at the time of y's assignment,
> exponentiation of x was legal, and at the time of z's, uppercasing
> was. 

Could it? Do you have an example of a language or type-checker that can do
that? This isn't a rhetorical question.

My understanding is that all the standard algorithms for checking types are
based on the principle that a variable only has a single type in any one
scope. Global x and local x may be different, but once you explicitly or
implicitly set x to an int, then you can't set it to a str. So I'm not sure
that existing compile-time type-checkers could deal with that, even in a
dynamic language. At best they might say "oh well, x is obviously
duck-typed, so don't bother trying to check it".

At least that's my understanding -- perhaps I'm wrong.

I daresay that what you want is *possible*. If the human reader can do it,
then an automated checker should be able to. The question is not "is this
possible?" but "has anyone done it yet?".


> But you said that the type system could flag the third line as an 
> error, saying "hey, I'm expecting this to be integers only". Here's
> what you said:
> 
>> x = 1
>> x = "hello"  # a type error, at compile time
>
> If I were doing type inference, with my limited knowledge of the
> field, I would do one of two things:
> 
> 1) Infer that x holds only integers (or maybe broaden it to
> "numbers"), and then raise an error on the second line; this basically
> restricts the type system to be union-free

No, it only means that the system won't *infer* type unions just from
assignmen

Re: Is duck-typing misnamed?

2016-08-28 Thread Steve D'Aprano
On Sun, 28 Aug 2016 08:34 am, Terry Reedy wrote:

> On 8/26/2016 7:58 PM, ROGER GRAYDON CHRISTMAN wrote:
>> "If it walks like a duck, quacks like a duck,... "
>>
>> so there is indeed precedence for this so-called 'duck typing'
>>
>>
>> but wouldn't it be more Pythonic to call this 'witch typing'?
>>
>> "How do you know she is a witch?"
>>
>> "She looks like one."
> 
> Given that people were once burned to death for 'looking like a witch'
> (or sounding or acting), and can still suffer socially for such reasons,
> this it not funny to me.  We should stick with ducks.

Black humour is still humour. And it is an important way of dealing with
distress, and of instituting social change.

Belief in the supernatural and superstition is on the rise again, including
witchcraft. If it were limited to just a few benighted and ignorant
migrants from Africa, that would be bad enough, but I see disturbing signs
that the Satanic Ritual panic from the 80s and 90s is on its way back. (Or
perhaps it never quite went away, just faded from the headlines.) Likewise
the anti-paedophile frenzy, where the mere (false) accusation of
paedophilia is enough to start a frenzy of abuse and even killing:

http://www.telegraph.co.uk/news/uknews/crime/10422771/How-wild-rumour-led-a-mob-to-murder-an-innocent-man.html

Black humour is a weapon against the ignorance and intolerance that feeds
hate crimes and witch hunts (whether legally sanctioned or not, whether
about literal witches or any other demonised subgroup). We can and should
take every opportunity to remind people of the absurdity of relying on
torture to gain confessions, and the abuses of this sort of single-minded,
hysterical moral panic. And humour is a most effective way to do so. Nobody
likes to be hectored and lectured as I'm lecturing you now *wink* but
turning it into a joke can get the point across.

We should not lose sight of the economic, political, racial reasons for
witch-hunts, but equally we should not forget that when a moral panic is in
full force, people behave absurdly, and the best antidote to absurd
behaviour is to take the mickey out of it.



-- 
Steve
“Cheer up,” they said, “things could be worse.” So I cheered up, and sure
enough, things got worse.

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


Re: What's the best way to minimize the need of run time checks?

2016-08-28 Thread Chris Angelico
On Mon, Aug 29, 2016 at 12:43 PM, Steve D'Aprano
 wrote:
> On Sun, 28 Aug 2016 07:28 pm, Chris Angelico wrote:
>
>> On Sun, Aug 28, 2016 at 6:33 PM, Steven D'Aprano
>>  wrote:
>>> On Sunday 28 August 2016 15:29, Chris Angelico wrote:
 It might be a good way of thinking about points on a Cartesian plane,
 though. Rectangular and polar coordinates truly are just different
 ways of expressing the same information.
>>>
>>> That's exactly my point, and that's why you shouldn't implement them as
>>> different classes. If you do, that's a limitation of your code and/or the
>>> language.
> [... snip digression over possible leaky abstractions due to floating point
> rounding ...]
>
>> class Complex(complex):
>> @property
>> def r(self):
>> return abs(self)
>> @property
>> def phi(self):
>> return cmath.phase(self)
>>
>> One value, two ways of looking at it. One type. One class.
>
> I can't tell if you're saying this to agree with me or to disagree with me.

Agreeing, and positing that you don't even need two ways of storing it
(modulo FP rounding) - just two ways of *looking* at it.

>>> I might be able to tell the compiler that x is Union[int, str] (a number,
>>> or a string) but that limits the ability of the compiler to tell what is
>>> and what isn't safe.
>>
>> That's fine if you *tell* the compiler this.
>
> I trust you don't actually mean that it is fine for a high-level
> (non-assembly) language to blindly execute some arbitrary memory address.

Quote trimmed to clarify my point. Of course I don't want a high level
language to blindly execute random memory.

> Your question seems to be, what happens if you follow that with an
> assignment to a different type?
>
> x = 5
> some_code(x)
> x = "hello world"
>
>
> Will the type-checker consider that an error ("you're assigning a str to an
> int") or will it infer that x is the Union[int, str]?
>
> Surely that depends on the type-checker! I don't think there's any hard and
> fast rule about that, but as far as I know, all statically typed languages
> consider than an error. Remember, that's the definition of *static typing*:
> the variable carries the type, not the value. So x is an int, and "hello
> world" isn't an int, so this MUST be an error.

So in statically-typed inferred-type languages, unions are impossible.
Got it. That's perfectly acceptable with strings and integers, but
ints and floats are more problematic. More on that below.

> In dynamically typed languages... I don't know. I think that (again) I would
> expect that *by default* the checker should treat this as an invalid
> assignment. The whole point of a static type-checker is to bring some
> simulacrum of static typing to a dynamic language, so if you're going to
> enthusiastically infer union types every time you see an unexpected type
> assignment, it sort of defeats the purpose...
>
> "x was declared int, and you then call function foo() which is declared to
> return an int, but sometimes returns a str... oh, they must have meant a
> union, so that's okay..."

Not really; you forfeit any kind of assignment checking (since
assignment will simply expand the type union), but you still get
static type checking of operators, methods, attributes, etc, and of
function calls (passing a string|int to something that expects a list?
Error!). You still get a lot of the benefit.

>> A dynamic type inference
>> system could easily cope with this:
>>
>> x = 5
>> y = x**2
>> x = "five"
>> z = x.upper()
>>
>> and correctly deduce that, at the time of y's assignment,
>> exponentiation of x was legal, and at the time of z's, uppercasing
>> was.
>
> Could it? Do you have an example of a language or type-checker that can do
> that? This isn't a rhetorical question.

No, I don't, because the type-checking languages I use have
declarations. But since C compilers are capable of detecting that
"this variable isn't used after this point, so I can reuse its
register", the equivalent in type checking should be possible.

> My understanding is that all the standard algorithms for checking types are
> based on the principle that a variable only has a single type in any one
> scope. Global x and local x may be different, but once you explicitly or
> implicitly set x to an int, then you can't set it to a str. So I'm not sure
> that existing compile-time type-checkers could deal with that, even in a
> dynamic language. At best they might say "oh well, x is obviously
> duck-typed, so don't bother trying to check it".
>
> At least that's my understanding -- perhaps I'm wrong.
>
> I daresay that what you want is *possible*. If the human reader can do it,
> then an automated checker should be able to. The question is not "is this
> possible?" but "has anyone done it yet?".

Understood. That's what I wanted to clear up - that type inference
systems aim for a single type for any given variable.

> No, it only means that the system won't *infer* type unions just from
> assignment. And t