The Cost of Dynamism (was Re: Pyhon 2.x or 3.x, which is faster?)

BartC bc at freeuk.com
Sat Mar 12 21:30:37 EST 2016


On 13/03/2016 02:01, Steven D'Aprano wrote:
> On Sun, 13 Mar 2016 10:57 am, BartC wrote:
>
>> I use 'const' everywhere in other languages, most often in the form of
>> sophisticated sets of enums. A single project might have 1000 or even
>> 2000. (Example that defines a set of byte-codes:
>> http://pastebin.com/q1UwjKmK)
>>
>> How does Python manage without them? Is it really necessary to declare
>> hundreds of individual variables and assign a value to each? (And risk
>> someone assigning a new value to them.)
>
> Copying from your code, you define a bunch of constants in a table (many of
> which apparently have the same value?):
>
> global tabledata()  cmdnames, cmdfmt =
>     (kzero=0,       $,  (0,0,0,0)),
>     (knop,          $,  (0,0,0,0)),
>     (klabel,        $,  (l,0,0,0)),
>     (kcodestart,    $,  (p,h,0,0)),
>     (kcodeend,      $,  (0,0,0,0)),
>     (kendmodule,    $,  (0,0,0,0)),
>     (kendprogram,   $,  (0,0,0,0)),
>     ...
> end
>
> I don't understand the syntax. You seem to have three columns in the table,
> a name, a $ whatever that is for, and some data (four values in a
> comma-separated parenthesised list), but the table appears to only define
> two columns (cmdnames, cmdfmt). Mysterious.

(Obviously my comments didn't work.. The table above is roughly 
equivalent to the following Python:

kzero       = 0   # define a bunch of enums (with auto-increment)
knop        = 1
klabel      = 2
kcodestart  = 3
kcodeend    = 4
kendmodule  = 5
kendprogram = 6
...

#define a list of matching names (the $ is a cheap gimmick to avoid 
#duplicating each name. The language ought to take care of accessing
#the names, but it doesn't):

cmdnames = ("kzero",
             "knop",
             "klabel",
             "kcodestart",
             "kcodeend",
             "kendmodule",
             "kendprogram",...)

#define matching format codes (the single letter codes are constants
#defined previously):

cmfmt = ( (0,0,0,0),
           (0,0,0,0),
           etc.

Clearly it is possible to write the above, but it's harder to maintain 
and read (inserting or deleting enum names, keeping the parallel lists 
aligned, and trying to read off which fmt corresponds to which enum).)

> In Python, we might similarly define a table, using a dict:
>
> tabledata = dict(
>      kzero=(0,0,0,0),
>      knop=(0,0,0,0)),
>      klabel=(l,0,0,0)),
>      kcodestart=(p,h,0,0)),
>      kcodeend=(0,0,0,0)),
>      kendmodule=(0,0,0,0)),
>      kendprogram=(0,0,0,0)),
>      ...
>      )
> So the amount of typing is comparable. If you have 200 symbolic names with
> associated data, one way or the other you have to enter 200 symbolic names
> and their associated data into your source code, regardless of whether they
> are called "constants", "enums", "variables" or "symbols".

There are all sorts of ways to do it in any language. But I found my 
method invaluable. And you do end up with actual compile-time constants 
for the codes on the left.

A simpler example:

enum (red,green,blue)

which is equivalent to:

  const red=1
  const green=2
  const blue=3

I've seen half a dozen ways of doing enums in Python, but some look 
really complicated for something so simple. And you still end up with a 
LOAD_GLOBAL for that 'red' value!

Worse if red, green, blue are defined in a class as then you need a 
lookup too. My example above defined 'open' enums, but they can be 
assigned to their own type:

  type lights = (red, amber, green)

Now it's necessary to say lights.green, but this is just the constant 3!

See, get rid of some of the dynamics, and lots of things become very 
easy. (But I don't think that's going to happen.)


-- 
Bartc



More information about the Python-list mailing list