Death to tuples!

G

Gabriel Zachmann

I was wondering why python doesn't contain a way to make things "const"?

If it were possible to "declare" variables at the time they are bound to
objects that they should not allow modification of the object, then we would
have a concept _orthogonal_ to data types themselves and, as a by-product, a
way to declare tuples as constant lists.

So this could look like this:

const l = [1, 2, 3]

def foo( const l ): ...

and also

const d = { "1" : 1, "2" : 2, ... }

etc.

It seems to me that implementing that feature would be fairly easy.
All that would be needed is a flag with each variable.

Just my tupence,
Gabriel.


--
/-----------------------------------------------------------------------\
| Any intelligent fool can make things bigger, more complex, |
| or more violent. It takes a touch of genius - and a lot of courage - |
| to move in the opposite direction. (Einstein) |
\-----------------------------------------------------------------------/
 
S

Steven D'Aprano

I was wondering why python doesn't contain a way to make things "const"?

If it were possible to "declare" variables at the time they are bound to
objects that they should not allow modification of the object, then we would
have a concept _orthogonal_ to data types themselves and, as a by-product, a
way to declare tuples as constant lists.

In an earlier thread, somebody took me to task for saying that Python
doesn't have variables, but names and objects instead.

This is another example of the mental confusion that occurs when you think
of Python having variables. Some languages have variables. Some do not. Do
not apply the rules of behaviour of C (which has variables) to Python
(which does not).

Python already has objects which do not allow modification of the object.
They are called tuples, strings, ints, floats, and other immutables.


So this could look like this:

const l = [1, 2, 3]

(As an aside, it is poor practice to use "l" for a name, because it is too
easy to mistake for 1 in many fonts. I always use capital L for quick
throw-away lists, like using x or n for numbers or s for a string.)

Let's do some tests with the constant list, which I will call L:


py> L.count(2)
1
py> L.append(4)
Traceback (most recent call last):
File "<stdin>", line 1, in ?
ConstantError: can't modify constant object

(Obviously I've faked that last error message.) So far so good: we can
call list methods on L, but we can't modify it.

But now look what happens when we rebind the name L:

py> L = 2
py> print L
2

Rebinding the name L doesn't do anything to the object that L pointed to.
That "constant list" will still be floating in memory somewhere. If L was
the only reference to it, then it will be garbage collected and the memory
it uses reclaimed.


Now, let's look at another problem with the idea of constants for Python:

py> L = [1, 2, 3] # just an ordinary modifiable list
py> const D = {1: "hello world", 2: L} # constant dict

Try to modify the dictionary:

py> D[0] = "parrot"
Traceback (most recent call last):
File "<stdin>", line 1, in ?
ConstantError: can't modify constant object

So far so good.

py> L.append(4)

What should happen now? Should Python allow the modification of ordinary
list L? If it does, then this lets you modify constants through the back
door: we've changed one of the items of a supposedly unchangeable dict.

But if we *don't* allow the change to take place, we've locked up an
ordinary, modifiable list simply by putting it inside a constant. This
will be a great way to cause horrible side-effects: you have some code
which accesses an ordinary list, and expects to be able to modify it. Some
other piece of code, could be in another module, puts that list inside a
constant, and *bam* your code will break when you try to modify your list.

Let me ask you this: what problem are you trying to solve by adding
constants to Python?


It seems to me that implementing that feature would be fairly easy.
All that would be needed is a flag with each variable.

Surely not. Just adding a flag to objects would not actually implement the
change in behaviour you want. You need to code changes to the parser to
recognise the new keyword, and you also need code to actually make objects
unmodifiable.
 
S

Steve Holden

Gabriel Zachmann wrote:
[...]
It seems to me that implementing that feature would be fairly easy.
All that would be needed is a flag with each variable.
It seems to me like it should be quite easy to add a sixth forward gear
to my car, but I'm quite sure an auto engineer would quickly be able to
point out several reasons why it wasn't, as well as questioning my
"need" for a sixth gear in the first place.

Perhaps you could explain why the absence of const objects is a problem?

regards
Steve
 
C

Christopher Subich

Gabriel said:
I was wondering why python doesn't contain a way to make things "const"?

If it were possible to "declare" variables at the time they are bound to
objects that they should not allow modification of the object, then we
would have a concept _orthogonal_ to data types themselves and, as a
by-product, a way to declare tuples as constant lists. ..
..
..
It seems to me that implementing that feature would be fairly easy.
All that would be needed is a flag with each variable.

Nope, that's not all you need; in fact, your definition of 'const'
conflates two sorts of constants.

Consider:
And
>>>const l = []
>>>l.append(foo) # error?

with its more general:
And none of this can prevent:
>>>d = {}
>>>const foo=[d]
>>>d['bar']='baz'

The first "constant" is the only well-defined one in Python: a constant
name. A "constant" name would prohibit rebinding of the name for the
scope of the name. Of course, it can't prevent whatsoever mutation of
the object which is referenced by the name.

Conceptually, a constant name would be possible in a python-like
language, but it would require significant change to the language to
implement; possibly something along the lines of name/attribute
unification (because with properties it's possible to have
nearly-constant[1] attributes on class instances).

The other form of constant, that of a frozen object, is difficult
(probably impossible) to do for a general object: without knowing ahead
of time the effects of any method invocation, it is very difficult to
know whether the object will be mutated. Combine this with exec/eval
(as the most absurd level of generality), and I'd argue that it is
probably theoretically impossible.

For more limited cases, and for more limited definitions of immutable,
and ignoring completely the effects of extremely strange code, you might
be able to hack something together with a metaclass (or do something
along the lines of a frozenset). I wouldn't recommend it just for
general use.

Really, the single best purpose of constant names/objects is for
compiler optimization, which CPython doesn't do as-of-yet. When it
does, possibly through the PyPy project, constants will more likely be
discovered automatically from analysis of running code.

[1] -- barring straight modification of __dict__
 
M

Magnus Lycka

Gabriel said:
I was wondering why python doesn't contain a way to make things "const"?

If it were possible to "declare" variables at the time they are bound to
objects that they should not allow modification of the object, then we
would have a concept _orthogonal_ to data types themselves and, as a
by-product, a way to declare tuples as constant lists.

So this could look like this:

const l = [1, 2, 3]

That was a bit confusing. Is it the name 'l' or the list
object [1, 2, 3] that you want to make const? If you want
to make the list object immutable, it would make more sense
to write "l = const [1, 2, 3]". I don't quite see the point
though.

If you could write "const l = [1, 2, 3]", that should logically
mean that the name l is fixed to the (mutable) list object
that initially contains [1, 2, 3], i.e. l.append(6) is OK,
but l = 'something completely different" in the same scope
as "const l = [1, 2, 3]" would be forbidden.

Besides, what's the use case for mutable numbers for instance,
when you always use freely rebindable references in your source
code to refer to these numbers. Do you want to be able to play
nasty tricks like this?
6

It seems to me that you don't quite understand what the
assignment operator does in Python. Please read
http://effbot.org/zone/python-objects.htm
 
T

Tom Anderson

In an earlier thread, somebody took me to task for saying that Python
doesn't have variables, but names and objects instead.

I'd hardly say it was a taking to task - that phrase implies
authoritativeness on my part! :)
This is another example of the mental confusion that occurs when you
think of Python having variables.

What? What does this have to do with it? The problem here - as Christopher
and Magnus point out - is the conflation in the OP's mind of the idea of a
variable, and of the object referenced by that variable. He could have
expressed the same confusion using your names-values-and-bindings
terminology - just replace 'variable' with 'name'. The expression would be
nonsensical, but it's nonsensical in the variables-objects-and-pointers
terminology too.
Some languages have variables. Some do not.

Well, there is the lambda calculus, i guess ...

tom
 
S

Steven D'Aprano

I'd hardly say it was a taking to task - that phrase implies
authoritativeness on my part! :)


What? What does this have to do with it? The problem here - as Christopher
and Magnus point out - is the conflation in the OP's mind of the idea of a
variable, and of the object referenced by that variable. He could have
expressed the same confusion using your names-values-and-bindings
terminology - just replace 'variable' with 'name'. The expression would be
nonsensical, but it's nonsensical in the variables-objects-and-pointers
terminology too.

If the OP was thinking names-and-bindings, he would have immediately
realised there is a difference between unmodifiable OBJECTS and
unchangeable NAMES, a distinction which doesn't appear to have even passed
his mind.

"Variable" is a single entity of name+value, so it makes perfect sense to
imagine a variable with a constant, unchangeable value. But a name+object
is two entities, and to implement constants you have to have both
unmodifiable objects and names that can't be rebound -- and even that may
not be sufficient.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,781
Messages
2,569,615
Members
45,301
Latest member
BuyPureganics

Latest Threads

Top