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
--
https://mail.python.org/mailman/listinfo/python-list

Reply via email to