Archive for May, 2020

Python is a Great Prototyping Language…but One Should Never Ship a Prototype

Tuesday, May 26th, 2020

I really like how Python lets me start to get things working before everything is working. I can fire up an interactive debugger and immediately start playing with some library I Googled up and think I might need, quickly get it doing stuff, plug it in to other code and quickly get the whole doing useful stuff.

I can get my Python program in a useful state before I have really decided what I wanted it to do, and well before I have stopped to think hard about the best way to do it.

This kind of exploratory programming is exactly what is needed to develop a prototype. But never “ship” the prototype!

Here is an analogy to the physical world: there are prototyping materials that are easy to work with but are not as durable nor economical as are materials suited to real manufacturing. For an extreme example, automobile bodies used to be prototyped, at least in part, with modeling clay. And the very properties that make modeling clay good for prototyping make it terrible for manufacturing. (Take it to go buy a Christmas tree, strapped on top.)

Similarly, in the case of Python, the key property that makes it good for prototyping, makes it terrible for “real” programs: Probably the biggest thing that makes Python powerful is precisely that it allows the programmer to defer so many decisions. What kind of parameter does the function take? “A parameter called X!” Not very useful. Even if the parameter is called something like “address_list”, that only hints–it might not actually be a list, maybe the address “list” is in a dictionary and the keys are customer numbers. (Likely.) And even if we really honestly know the address_list is a Python list. Okay…a list of what? Let’s guess dictionaries, Python loves dictionaries. And what will be in the dictionary? Whatever anyone anywhere else in the code might manage to put in there–or remove from there. And it gets worse: Some programmers think it is cool to put “**kwargs” in the parameters, which means we don’t even know what the parameters to the function are! We have to examine every line of code that might call this function to see what the possible parameters are, and even then you will see (you just now it) that some of that code is going to be passing a dictionary that is only known at runtime.

The fact the programmer doesn’t have to decide what s/he is doing can give the illusion that real programming is happening really fast, but there is an illusion there. A dangerous and beguiling illusion. Worse, of course, is when such dynamic features are actively abused (see kwargs), but merely deciding to use a simple list yet having no good way to pin down what is in it is such a rich place to hide bugs.

Strongly Typed Language: Python

There is this idea that compiled languages such as C (or C++, all the weaknesses of C without the virtues of being a small and elegant language) are strongly typed but an interpreted language such as Python is not. This is half-right.

In C you have to say what kind of data goes into your variable.

In Python you can put whatever you want in your variable–a string, a boolean, some kind of number, some enormous data structure, a function, or None. Not only can you put what you want in there, you can change it at your whim; in one line the you might declare an instance of the class your variable holds, and a couple of lines later (or a different thread, if it can get a chance to run) set your variable to 42. Python is very liberal about such things.

But this doesn’t mean Python isn’t strongly typed! It is very strongly typed, it just doesn’t make up its mind about types until the last possible moment, at runtime. Repeatedly. Every time through your loop.

In fact, Python does almost nothing but constantly checking types of things. It takes much longer to check the types of two variables for adding than it takes to actually add them. (To check whether they are numbers and that adding is sensible, and how to add these particular numbers–assuming they proved to be numbers. Python needs to check a lot before it can do the addition.)

Deferred Work Doesn’t Go Away

It is presumably important to you that when the Python code runs it not crash. One would think. In which case doing that clever thing of instantiating a class instance from a variable at one moment and doing arithmetic on 42 the next had better be done right because the reverse operations will not work. Even doing unclever things, such as misspelling a variable name and accidentally doing arithmetic on a class definition with a similar spelling is a bad idea.

And though Python will catch both of these mistakes if you make them, it will only do so if you exercise the right lines of code with the right (unfortunate) values. And only if the right person is watching in the right way will it do any good.

It is really hard to thoroughly exercise code. And in the case of a very dynamic language like Python the permutations are so great that it really isn’t possible.

Yes, Compilers are Annoying

In statically typed, compiled languages, it is more work to make the compiler happy, but a benefit is the compiler will prevent these sorts of errors. It is less work in total to catch a type problem up-front than to have to do it in the debugger and in vague bug reports from users. Unless you are planning to defer some of the work forever, planning on never finding and fixing some of the bugs…

Yes, Compilers are Inflexible

Yes. And in a good way, if it prevents accidentally doing arithmetic on a class definition.

But what about cases where one needs to be clever. Maybe not so clever as to mess with class definitions at runtime, but something more conventional, such as wanting either a value like 42 or some other flag value (such as Python’s None), isn’t that reasonable?

Yes. And compiled languages allow such things. Some in safe ways, even.

(Some Compilers are Nice)

The Rust compiler is demanding but in exchange lots of bugs simply won’t exist once the compiler is happy.

Rust: Not as slow as C without being as low-level as Python.

Prototypes are Expensive to Operate

I would like to see some hard numbers, but it feels to me like Python must spend a hundred times as much effort constantly checking the runtime type of every bit of data as it does doing real work on that data. Certainly Python is not very efficient, whatever the ratio. How much carbon is released just because of Python?

-kb, the Kent who is looking opportunities to finally get good at Rust.

P.S. Comments are broken and have been for sometime. Sorry.

©2020 Kent Borg

Patron Saint of Ham Radio?

Monday, May 18th, 2020

Today, 19 May 2020, is Oliver Heaviside’ 170th birthday.

Hurray!

Who?

Okay this post will be a bit technical…but only a bit.

One of the giants of science is James Clerk Maxwell, he figured out the science behind how radio waves work. Pretty important stuff. He is immortalized in the famous four Maxwell Equations. Maybe you have head of them, lots of science-y types have heard of them, but not that many understand them, so don’t feel too left out, this is rarefied territory. (I’m still learning this stuff, but I’m not there yet.) But it seems they are important to the experts that make modern life work.

And Maxwell did them!

Except he didn’t. Maxwell did eight equations, not four. Oliver Heaviside is the one who simplified the eight into four.

People will write otherwise, but it seems to me that it was Heaviside, not Maxwell, who created the whole field of electrical engineering.

In Heaviside’s day the hot new technology was the telegraph. You know, Morse code, dits and dahs. It was slow and cumbersome and expensive, but it could communicate over long distances very rapidly when compared with a horse or ship or even a racing locomotive (that means a train). The slight detail is that the longer the wires got the mushier the signal got. People would try to make up for it by turning up the voltage, and they had other tricks they tried, but it was a seat-of-the-pants, rule-of-thumb world, and don’t ask too many questions because even the most talented “electricians” didn’t really know why one trick might work and why a different did not. The first trans-Atlantic cable was not only very slow but burned out after a very short amount of use. (They turned up the voltage quite a bit.)

Heaviside worked for a telegraph company, and he wanted to figure out this stuff worked. Precisely how it worked, as in quantifying things. This rubbed some in the industry the wrong way, there was a lot of opposition of quantifying these things. And he did. Both rub people the wrong way and figure out these things. He figured out how to make telegraph wires operate at much faster speeds for much greater distances, without burning them out. His same principles were applied to voice telephone calls, for they had the same problem of the signal getting mushy if the lines got too long, and he explained how to fix that, too.

His solution was to set up what is now called a balanced transmission line. Back when TV antennas were put on roofs the first kind of cable for connecting it to the TV was a balanced transmission line, 300-ohm twin lead, to be precise, and it was a flat cable, made of plastic with a wire running down each edge. Don’t tape it directly to your metal antenna mast, it doesn’t like that, but if suspended away from metal, it is very efficient at getting a very weak signal down to the TV without picking up interference along they way. Heaviside invented the balanced transmission line. And it is useful for a lot more than ancient TV antennas. It you haven’t heard of balanced transmission line, but have heard of coax cable (it is perfectly okay to tape coax to the metal TV antenna mast–coax is not as efficient as twin lead, but easier to string), well Heaviside invented coaxial cable, too.

About the time telegraph and telephone were still pretty new there was another hot technology: radio. Heaviside was paying attention there, too. At this point sensible people knew the world was not flat but is round (spherical, to be pedantic). And people also knew that radio waves travel in straight lines, so radio wouldn’t be useful for long distance communications, right? Wrong. For some frequencies, under the right conditions, radio waves will bounce off the ionosphere and can travel great distances. Heaviside figured this out. He figured out that this should work before people found out that it did work. In fact the layer of the atmosphere (the ionosphere) that does this was originally called the Heaviside Layer.

Back to the Maxwell Equations. The way that Heaviside did all of this was by taking the science and figuring out how to apply it in a precise way to make an engineering discipline: he created electrical engineering. Including inventing new ways of doing the math.

In the early days of Bell Labs they were working magic by taking Heaviside’s work and applying it in a practical way. Some Bell engineers were so impressed with Heaviside’s work, and so indebted to him, that they tried to send him money, but he said no.

At this point Heaviside was old and not rich, yet he said no. Oliver Heaviside could be difficult. Various folk tried to help him and to the extent it looked like help to him, he said no, even though he needed it. And part of why the Bell Labs engineers were having such a hay day on his work is he that, though he might have been brilliant, he didn’t stop to try to make his work easy to understand, it took awhile for his work to have full effect.

Back to the my claim he should be the patron saint of ham radio: He made practical much of what the field is built on, he was a hands-on man. And he died of complications from falling from a ladder.

-kb, AC1HJ

©2020 Kent Borg

P.S. Comments are broken and have been for sometime. Sorry.