On Thu, Aug 25, 2016 at 08:46:54PM -0700, Ken Kundert wrote: > This idea is new to general purpose languages,
For the record, at least some HP calculators include a "units" data type as part of the programming language "RPL", e.g. the HP-28 and HP-48 series. I've been using those for 20+ years so I'm quite familiar with how useful this feature can be. > but it has been used for over 40 > years in the circuit design community. Specifically, SPICE, an extremely > heavily > used circuit simulation package, introduced this concept in 1974. In SPICE > the > scale factor is honored but any thing after the scale factor is ignored. > Being > both a heavy user and developer of SPICE, I can tell you that in all that > time > this issue has never come up. In fact, the users never expected there to be > any > support for dimensional analysis, nor did they request it. I can't comment about the circuit design community, but you're trying to extrapolate from a single specialist application to a general purpose programming language used by people of many, many varied levels of expertise, of competence, with many different needs. It makes a lot of sense for applications to allow SI prefixes as suffixes within a restricted range. For example, the dd application allows the user to specify the amount of data to copy using either bytes or blocks, with optional suffixes: BLOCKS and BYTES may be followed by the following multiplicative suffixes: xM M, c 1, w 2, b 512, kB 1000, K 1024, MB 1000*1000, M 1024*1024, GB 1000*1000*1000, G 1024*1024*1024, and so on for T, P, E, Z, Y. (Quoting from the man page.) That makes excellent sense for a specialist application where numeric quantities always mean the same thing, or in this case, one of two things. As purely multiplicative suffixes, that even makes sense for Python: earlier I said that it was a good idea to add a simple module defining SI and IEC multiplicative constants in the std lib so that we could do x = 42*M or similar. But that's a far cry from allowing and ignoring units. > > Don't think of people writing code like this: > > > > result = 23mA + 75MHz > > > > which is obviously wrong. Think about them writing code like this: > > > > total = sum_resistors_in_parallel(input, extra) > > You say that '23mA + 75MHz' is obviously wrong, but it is only obviously > wrong > because the units are included, which is my point. If I had written '0.023 > + 76e6', it would not be obviously wrong. I understand your point and the benefit of dimensional analysis. But the problem is, as users of specialised applications we may be used to doing direct arithmetic on numeric literal values, with or without attached units: 23mA + 75MHz # error is visible 23 + 75 # error is hidden but as *programmers* we rarely do that. Generally speaking, it is rare to be doing arithmetic on literals where we might have the opportunity to attach a unit. We doing arithmetic on *variables* that have come from elsewhere. Reading the source code doesn't show us something that might be improved by adding a unit: # we hardly ever see this 23 + 75 # we almost always see something like this input + argument At best, we can choose descriptive variable names that hint what the correct dimensions should be: weight_of_contents + weight_of_container The argument that units would make it easier for the programmer to spot errors is, I think, invalid, because the programmer will hardly ever get to see the units. [...] > Indeed that is the point of dimensional analysis. However, despite the > availability of all these packages, they are rarely if ever used because you > have to invest a tremendous effort before they can be effective. For example, > consider the simple case of Ohms Law: > > V = R*I > > To perform dimensional analysis we need to know the units of V, R, and I. > These > are variables not literals, so some mechanism needs to be provided for > specifying the units of variables, even those that don't exist yet, like V. This is not difficult, and you exaggerate the amount of effort required. To my sorrow, I'm not actually familiar with any of the Python libraries for this, so I'll give an example using the HP-48GX RPL language. Suppose I have a value which I am expecting to be current in amperes. (On the HP calculator, it will be passed to me on the stack, but the equivalent in Python will be a argument passed to a function.) For simplicity, let's assume that if it is a raw number, I will trust that the user knows what they are doing and just convert it to a unit object with dimension "ampere", otherwise I expect some sort of unit object which is dimensionally compatible: 1_A CONV is the RPL program to perform this conversion on the top of the stack, and raise an error if the dimensions are incompatible. Converting to a more familiar Python-like API, I would expect something like: current = Unit("A").convert(current) or possibly: current = Unit("A", current) take your pick. That's not a "tremendous" amount of effort, it is comparable to ensuring that I'm using (say) floats in the first place: if not isinstance(current, float): raise TypeError > And what if the following is encountered: > > V = I > > Dimensional analysis says this is wrong, That's because it is wrong. > but the it may be that the resistance > is simply being suppressed because it is unity. Your specialist experience in the area of circuit design is misleading you. There's effectively only one unit of resistance, the ohm, although my "units" program also lists: R_K 25812.807 ohm abohm abvolt / abamp intohm 1.000495 ohm kilohm kiloohm megohm megaohm microhm microohm ohm V/A siemensunit 0.9534 ohm statohm statvolt / statamp So even here with resistence "unity" is ambiguous. Do you mean one intohm, one microhm, one statohm or something else? I'll grant you that in the world of circuit design perhaps it could only mean the SI ohm. But you're not in the world of circuit design any more, you are dealing with a programming language that will be used by people for many, many different purposes, for whom "unity" might mean (for example): 1 foot per second 1 foot per minute 1 metre per second 1 kilometre per hour 1 mile per hour 1 lightspeed 1 knot 1 mach Specialist applications might be able to take shortcuts in dimensional analysis when "everybody knows" what the suppressed units must be. General purpose programming languages *cannot*. It is better NOT to offer the illusion of dimensional analysis than to mislead the user into thinking they are covered when they are not. Better to let them use a dedicated units package, not build a half-baked bug magnet into the language syntax. -- Steve _______________________________________________ Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas Code of Conduct: http://python.org/psf/codeofconduct/