472,141 Members | 950 Online
Bytes | Software Development & Data Engineering Community
Post +

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 472,141 software developers and data experts.

Possible constant assignment operators ":=" and "::=" for Python

Hi Pythonians,

To begin with I'd like to apologize that I am not very experienced
Python programmer so please forgive me if the following text does not
make any sense.

I have been missing constants in Python language. There are some
workarounds available, for example the const-module. To me, this looks
quite cumbersome and very unintuitive. For the interpreter, in the
efficiency-wise, I just cannot tell.

For the solution I came up with two new assignment operators to the
language which would create a constant name and constant value: Let's
welcome the new constant assignment operators := and ::=

The := assignment operator says that "declare the name to be constant
and immutable". However, there might be some side-effects and the
constant may not always be constant as you will see below:

a = [1, 2, 3]
b := [4, 5, 6] # assign [4,5,6] to 'b' and declare name 'b' to
be "constant" and "immutable"
c := a # assign 'a' to 'c' and declare that name 'c' is
"constant" and "immutable"
d = c # assign 'c' to 'd' and 'd' inherits the
"immutable"-attribute from 'c', but 'd' can be assigned
later
e = d # assign 'd' to 'e' and 'e' inherits the
"immutable"-attribute from 'd', but 'e' can be assigned
later
a.append( b )
print a # prints [1, 2, 3, 4, 5, 6]
print c # prints [1, 2, 3, 4, 5, 6] because of the side-effect
print d # prints [1, 2, 3, 4, 5, 6] as well
print e # prints [1, 2, 3, 4, 5, 6] no magic here
c = b # 'c' cannot be assigned as 'c' is "constant"
c := b # 'c' cannot be redefined either as 'c' is
"constant"
c.append( 7 ) # cannot be done as 'c' is "immutable"
d.append( 7 ) # cannot be done as 'd' is "immutable" as it was
inherited from 'c'.
e.append( 7 ) # cannot be done as 'e' is "immutable" as it was
inherited from 'd'.
d = [7, 8, 9] # normal variable assignment because 'd' was not
declared to be a "constant"
d.append( 10 ) # now allowed as 'd' is not "immutable" any more

The ::= copy&assign-operator says that "make a copy of the
right-hand-side object and declare the name to be constant and
immutable ". This would give us a true constant object which cannot be
changed. Example follows:

a = [1, 2, 3]
b = [4, 5, 6]
c ::= a # make copy of 'a' and assign that new copy to 'c' and
declare that name 'c' is a "constant" and "immutable"
d = c # assign 'c' to 'd' and 'd' inherits the
"immutable"-attribute from 'c', but 'd' can be assigned
later
e := d # assign 'd' to 'e' and declare that name 'e' is
"constant" and "immutable"
a.append( b )
print a # prints [1, 2, 3, 4, 5, 6]
print c # prints [1, 2, 3] as 'a' and 'c' are two different
objects because of the ::=
print d # prints [1, 2, 3] no magic here
print e # prints [1, 2, 3] no magic here either
c = b # 'c' cannot be assigned as 'c' is "constant"
c := b # 'c' cannot be redefined either as 'c' is
"constant"
c.append( 7 ) # cannot be done as 'c' is "immutable"
d.append( 7 ) # cannot be done as 'd' is "immutable" as it was
inherited from 'c'.
e.append( 7 ) # cannot be done as 'e' is "immutable" as it was
inherited from 'd'.
d = [7, 8, 9] # normal variable assignment because 'd' was not
declared to be a "constant"
d.append( 10 ) # now allowed as 'd' is not "immutable" any more

The := operator would be computionally efficient as it creates only a
reference to an existing object but it may suffer from side-effects.
The ::= is less efficient as it makes a copy on an existing object, but
gives truly constant objects.

Does this make any sense to you, or are there some fatal issues that I
just happened to overlook?

Br,

T.S.

Apr 28 '06 #1
25 2426
ts*******@yahoo.com wrote:
To begin with I'd like to apologize that I am not very experienced
Python programmer so please forgive me if the following text does not
make any sense.

I have been missing constants in Python language. There are some
workarounds available, for example the const-module. To me, this looks
quite cumbersome and very unintuitive. For the interpreter, in the
efficiency-wise, I just cannot tell.


The question is, why have you been missing them? Constants serve a
variety of purposes in other languages, some of which might not be
worthwhile in Python. There was a thread about 'symbols' a while back
which covers many of the uses of constants.

--
Ben Sizer

May 2 '06 #2
ts*******@yahoo.com a écrit :
Hi Pythonians,

To begin with I'd like to apologize that I am not very experienced
Python programmer so please forgive me if the following text does not
make any sense.

I have been missing constants in Python language.


Why so ?

I guess you're talking about named (symbolic) constants ? If so, just
follow the convention : a name in ALL_UPPERCASE is a constant (or at
least will be treated as such by anyone not wanting to mess with your
package's implementation). No need to add extra syntax here IMHO.
May 2 '06 #3
Bruno Desthuilliers wrote:
ts*******@yahoo.com a écrit :
Hi Pythonians,

To begin with I'd like to apologize that I am not very experienced
Python programmer so please forgive me if the following text does not
make any sense.

I have been missing constants in Python language.


Why so ?

I guess you're talking about named (symbolic) constants ? If so, just
follow the convention : a name in ALL_UPPERCASE is a constant (or at
least will be treated as such by anyone not wanting to mess with your
package's implementation). No need to add extra syntax here IMHO.


Hi Bruno,

For example:
A = [] # let's declare a "constant" here
b = A # and let's assign the constant here
b.append('1') # OOPS!
c = A
print A ['1'] print b ['1'] print c

['1']

As you can see, the "constant" A can be modified this easily. But if
there were an intuitive mechanism to declare a symbol to be immutable,
then there won't be this problem.

Br,

- T.S.

May 3 '06 #4
ts*******@yahoo.com wrote:
For example:
A = [] # let's declare a "constant" here
b = A # and let's assign the constant here
b.append('1') # OOPS!
c = A
print A ['1'] print b ['1'] print c ['1']

As you can see, the "constant" A can be modified this easily. But if
there were an intuitive mechanism to declare a symbol to be immutable,
then there won't be this problem.


why are you using mutable objects as constants?

(insert obligatory "it hurts when I do this" joke here)

btw, given a hypothetical "object that symbol points to is immutable" syntax,
what would you expect this to do ?
constant A = [] b = [A] # much later
b[0].append('1')


</F>

May 3 '06 #5
Yes, I know that "constant" A will also be modified as the b[0] points
to A. Obviously the [] should be marked as immutable, as A is declared
to be constant thus immutable. If somebody tries to modify this
immutable object an error would occur.

When I further thought about this problem with constant objects (and
values), I run into this scenario: What if I want to use a constant
object/value as a template (or predefined value/class) for a variable:

constant A = ['1'] # let's declare A as immutable constant value/object
b = A # let's assign b some default value
b.append('2') # and let's play with b, but I wouldn't want to change A

What I'd like to see here is that b gets a copy of A so that the
original A won't be modified as we play with b. However, as we assign a
constant value A to b, I wouldn't want to restrict myself from playing
with b. Of course, I could write something like b = list(A) to get a
copy of A assigned to b. However, in this situation I have to know the
class name of A. But this is something that I would no like to have to
know if we want to take modules as some kind of black boxes.

Br,

T.S.

May 3 '06 #6
ts*******@yahoo.com wrote:
Yes, I know that "constant" A will also be modified as the b[0] points
to A. Obviously the [] should be marked as immutable, as A is declared
to be constant thus immutable. If somebody tries to modify this
immutable object an error would occur.


so a constant declaration doesn't only affect the namespace, it also modifies
the type of the object ?

are you sure you know how Python's object model work ? if you do, please
explain your proposal in terms of what needs to be changed, rather than in
terms of wishful thinking.

</F>

May 3 '06 #7
> are you sure you know how Python's object model work ? if you do, please
explain your proposal in terms of what needs to be changed, rather than in
terms of wishful thinking.


No, I do not know. As stated in my first post, I am quite newbie in
Python and miss a simple and intuitive mechanism that would allow to
declare something as constant and that would protect these "constant"
objects from accidental modifications.

T.S.

May 3 '06 #8
Fredrik Lundh a écrit :
ts*******@yahoo.com wrote:

For example:

>A = [] # let's declare a "constant" here
>b = A # and let's assign the constant here
>b.append('1') # OOPS!
>c = A
>print A


['1']
>print b


['1']
>print c


['1']

As you can see, the "constant" A can be modified this easily. But if
there were an intuitive mechanism to declare a symbol to be immutable,
then there won't be this problem.

why are you using mutable objects as constants?

(insert obligatory "it hurts when I do this" joke here)

btw, given a hypothetical "object that symbol points to is immutable" syntax,
what would you expect this to do ?
>>> constant A = [] >>> b = [A] >>> # much later
>>> b[0].append('1')
That's easy, since A is a symbolic constant know at compile time, and
since it's a known mutable objet, the code once compiled will be
equivalent to:
b = [[]] # much later
b|0].append('1')

May 3 '06 #9
ts*******@yahoo.com wrote:
As stated in my first post, I am quite newbie in
Python and miss a simple and intuitive mechanism that would allow to
declare something as constant and that would protect these "constant"
objects from accidental modifications.

T.S.


Python solution is to rely on the intelligence of programmers. If they
see
an all caps name and then they try to change it without knowing what
they are doing,
then they are stupid. If you have stupid programmers there is no way
the
language can stop them for making disasters.
For true constants, this is the end of the story. OTOH, sometimes you
want
read-only attributes which should not be accidentally overwritten but
that
are not really constants. In this case, the solution is to use
properties.
Just google the newsgroup for "properties" and you will find many
examples
of usage.

Michele Simionato

May 3 '06 #10
Michele Simionato wrote:
Python solution is to rely on the intelligence of programmers. If they
see an all caps name and then they try to change it without knowing what
they are doing, then they are stupid. If you have stupid programmers there
is no way the language can stop them for making disasters.


Which doesn't apply here, one of the OP's examples further up this thread
doesn't modify any ALL CAPS vars directly:
A = []Â*Â*#Â*let'sÂ*declareÂ*aÂ*"constant"Â*here
b = AÂ*Â*Â*#Â*andÂ*let'sÂ*assignÂ*theÂ*constantÂ*here
b.append('1') # OOPS!

May 3 '06 #11
ts*******@yahoo.com wrote:
What I'd like to see here is that b gets a copy of A so that the
original A won't be modified as we play with b. However, as we assign a
constant value A to b, I wouldn't want to restrict myself from playing
with b.


If A is a list you can take a copy-slice liek this:
b = A[:]


and changes to b won't affect A. For the general case where A isn't a list,
you can use the copy module to make shallow or deep copies of A.

http://docs.python.org/lib/module-copy.html

It's not quite as simple or as strict as declaring A constant, but it works.
Or you could look at properties, there's a thread in this group within the
last couple weeks about making constants with properties.

May 3 '06 #12
Edward Elliott wrote:
Michele Simionato wrote:
Python solution is to rely on the intelligence of programmers. If they
see an all caps name and then they try to change it without knowing what
they are doing, then they are stupid. If you have stupid programmers
there is no way the language can stop them for making disasters.


Which doesn't apply here, one of the OP's examples further up this thread
doesn't modify any ALL CAPS vars directly:
A = []Â*Â*#Â*let'sÂ*declareÂ*aÂ*"constant"Â*here
b = AÂ*Â*Â*#Â*andÂ*let'sÂ*assignÂ*theÂ*constantÂ*here
b.append('1') # OOPS!


That leads to the question of forbidding mutable methods. Which will require
const-declarations on methods that in turn are only allowed to invoke
const-methods themselves.

Bottom line is: if one wants static typing and full control over
construction of new pobjects when merely assigning, use C++ :)

diez
May 3 '06 #13
Christophe wrote:
That's easy, since A is a symbolic constant know at compile time, and
since it's a known mutable objet, the code once compiled will be
equivalent to:
>>> b = [[]] >>> # much later
>>> b|0].append('1')
the OP talked about constants as names for immutable objects, not pre-
processor macros. but alright, using the "symbolic constant" approach,
what would this print ?
def foo(var): ... var.append('1')
... print var
... b = []
foo(b)
foo(b)
and this ?
constant A = []
print A is A


</F>

May 4 '06 #14
Fredrik Lundh a écrit :
Christophe wrote:

That's easy, since A is a symbolic constant know at compile time, and
since it's a known mutable objet, the code once compiled will be
equivalent to:
>>> b = [[]]
>>> # much later
>>> b|0].append('1')

the OP talked about constants as names for immutable objects, not pre-
processor macros. but alright, using the "symbolic constant" approach,
what would this print ?
>>> def foo(var): ... var.append('1')
... print var
... >>> b = []
>>> foo(b)
>>> foo(b)

I think you've made a mistake in your example. This is valid today's
Python you know :) And it'll print more or less :
['1']
['1', '1']
and this ?
>>> constant A = []
>>> print A is A


Obviously, False.
May 4 '06 #15
Edward Elliott wrote:
Michele Simionato wrote:
Python solution is to rely on the intelligence of programmers. If they
see an all caps name and then they try to change it without knowing what
they are doing, then they are stupid. If you have stupid programmers there
is no way the language can stop them for making disasters.


Which doesn't apply here, one of the OP's examples further up this thread
doesn't modify any ALL CAPS vars directly:
A = [] # let's declare a "constant" here
b = A # and let's assign the constant here
b.append('1') # OOPS!


But it makes no sense to use a mutable object for a constant!
The user should use a tuple, or a custom list-like type where
all methods with side effects are removed, so it effectively acts
as a tuple.

Michele Simionato

May 4 '06 #16
Michele Simionato wrote:
>>> A = [] # let's declare a "constant" here
>>> b = A # and let's assign the constant here
>>> b.append('1') # OOPS!

But it makes no sense to use a mutable object for a constant!
The user should use a tuple,


Sure. Now show me the builtin immutable equivalent of a dict.
or a custom list-like type where
all methods with side effects are removed, so it effectively acts
as a tuple.


Ugh, not worth the trouble imo.
May 4 '06 #17
ts*******@yahoo.com a écrit :
Bruno Desthuilliers wrote:
ts*******@yahoo.com a écrit :
Hi Pythonians,

To begin with I'd like to apologize that I am not very experienced
Python programmer so please forgive me if the following text does not
make any sense.

I have been missing constants in Python language.
Why so ?

I guess you're talking about named (symbolic) constants ? If so, just
follow the convention : a name in ALL_UPPERCASE is a constant (or at
least will be treated as such by anyone not wanting to mess with your
package's implementation). No need to add extra syntax here IMHO.

Hi Bruno,

For example:

A = [] # let's declare a "constant" here


Uh ? That's the strangest idea I've ever seen - I mean, using an empty
list as a constant... If you need your constant to be a sequence (while
I can't imagine any reason to do so), use a tuple.

(snip)
As you can see, the "constant" A can be modified this easily. But if
there were an intuitive mechanism to declare a symbol to be immutable,


Don't worry about the symbol, use an immutable type !-)
May 4 '06 #18
ts*******@yahoo.com a écrit :
Yes, I know that "constant" A will also be modified as the b[0] points
to A. Obviously the [] should be marked as immutable, as A is declared
to be constant thus immutable. If somebody tries to modify this
immutable object an error would occur.

When I further thought about this problem with constant objects (and
values), I run into this scenario: What if I want to use a constant
object/value as a template (or predefined value/class) for a variable:

constant A = ['1'] # let's declare A as immutable constant value/object
b = A # let's assign b some default value
b.append('2') # and let's play with b, but I wouldn't want to change A


def A():
return ['1']

b = A()
b.append('2')
May 4 '06 #19
Edward Elliott wrote:
Michele Simionato wrote:
>>> A = [] # let's declare a "constant" here
>>> b = A # and let's assign the constant here
>>> b.append('1') # OOPS!


But it makes no sense to use a mutable object for a constant!
The user should use a tuple,


Sure. Now show me the builtin immutable equivalent of a dict.


There is none. However it is pretty easy to get one:

import UserDict

class ReadOnlyDict(UserDict.DictMixin):
def __init__(self, dic):
self._dic = dic
def __getitem__(self, name):
return self._dic[name]
def keys(self):
return self._dic.keys()
def __getitem__(self, name):
raise TypeError('this dictionary is read-only')
def __delitem__(self, name):
raise TypeError('this dictionary is read-only')

I am sure you already know that, this snipped is for the benefit of the
other
readers of this thread. Of course, the ReadOnlyDict can be modified by
modifying ._dic, but the point was all about avoiding accidental
modifications.
or a custom list-like type where
all methods with side effects are removed, so it effectively acts
as a tuple.


Ugh, not worth the trouble imo.


Agreed, use a tuple if you need a tuple.

Michele Simionato

May 5 '06 #20
Christophe wrote:
I think you've made a mistake in your example.

constant A = []
def foo(var): ... var.append('1')
... print var
... b = A
foo(b)
foo(b)
and this ?
>>> constant A = []
>>> print A is A


Obviously, False.


why obviously ? why shouldn't a constant be constant ?

</F>

May 5 '06 #21
Fredrik Lundh a écrit :
Christophe wrote:

I think you've made a mistake in your example.


>>> constant A = []
>>> def foo(var): ... var.append('1')
... print var
... >>> b = A
>>> foo(b)
>>> foo(b)
and this ?

>>> constant A = []
>>> print A is A


Obviously, False.

why obviously ? why shouldn't a constant be constant ?

</F>


Because the name A is bound by the compiler to mean construct a new
object since [] is mutable.

Same reason why :
def A(): return []
print A() is A()

False

It gives btw one possible implementation ;)
May 10 '06 #22
>>>>> ts*******@yahoo.com (T) wrote:
T> As you can see, the "constant" A can be modified this easily. But if
T> there were an intuitive mechanism to declare a symbol to be immutable,
T> then there won't be this problem.


Mutability is not a property of symbols but of values. So it doesn't make
sense to declare an identifier to be immutable. And mutability is tied to
the object's type, not to individual instances.

What you want can only be obtained if Python would have an immutable
variant for each type or would add an immutable attribute to each object.
--
Piet van Oostrum <pi**@cs.uu.nl>
URL: http://www.cs.uu.nl/~piet [PGP 8DAE142BE17999C4]
Private email: pi**@vanoostrum.org
May 12 '06 #23
Piet van Oostrum wrote:
>> ts*******@yahoo.com (T) wrote:

T> As you can see, the "constant" A can be modified this easily. But if
T> there were an intuitive mechanism to declare a symbol to be immutable,
T> then there won't be this problem.


Mutability is not a property of symbols but of values. So it doesn't make
sense to declare an identifier to be immutable. And mutability is tied to
the object's type, not to individual instances.


I think he meant immutable binding, not immutable symbol. So
rebinding/overshadowing a "constant" A would raise an error, but mutating
the underlying object A refers to would not (unless it too were immutable).
As far objects themselves, adding an ability to make any object immutable
regardless of type is exactly what he suggests.

--
Edward Elliott
UC Berkeley School of Law (Boalt Hall)
complangpython at eddeye dot net
May 12 '06 #24
>>>>> Edward Elliott <no****@127.0.0.1> (EE) wrote:
EE> Piet van Oostrum wrote:
>>>> ts*******@yahoo.com (T) wrote:
T> As you can see, the "constant" A can be modified this easily. But if
T> there were an intuitive mechanism to declare a symbol to be immutable,
T> then there won't be this problem.
Mutability is not a property of symbols but of values. So it doesn't make
sense to declare an identifier to be immutable. And mutability is tied to
the object's type, not to individual instances.
EE> I think he meant immutable binding, not immutable symbol. So
EE> rebinding/overshadowing a "constant" A would raise an error, but
EE> mutating the underlying object A refers to would not (unless it too
EE> were immutable).


The way I understood it was that he meant both.
--
Piet van Oostrum <pi**@cs.uu.nl>
URL: http://www.cs.uu.nl/~piet [PGP 8DAE142BE17999C4]
Private email: pi**@vanoostrum.org
May 15 '06 #25
Piet van Oostrum wrote:
>>Edward Elliott <no****@127.0.0.1> (EE) wrote:


EE> Piet van Oostrum wrote:
>>>>>ts*******@yahoo.com (T) wrote:

T> As you can see, the "constant" A can be modified this easily. But if
T> there were an intuitive mechanism to declare a symbol to be immutable,
T> then there won't be this problem.
Mutability is not a property of symbols but of values. So it doesn't make
sense to declare an identifier to be immutable. And mutability is tied to
the object's type, not to individual instances.


EE> I think he meant immutable binding, not immutable symbol. So
EE> rebinding/overshadowing a "constant" A would raise an error, but
EE> mutating the underlying object A refers to would not (unless it too
EE> were immutable).

The way I understood it was that he meant both.


The way I understood it was that he didn't understand it. But then he
was gracious enough to admit that under questioning.

regards
Steve
--
Steve Holden +44 150 684 7255 +1 800 494 3119
Holden Web LLC/Ltd http://www.holdenweb.com
Love me, love my blog http://holdenweb.blogspot.com
Recent Ramblings http://del.icio.us/steve.holden

May 18 '06 #26

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

2 posts views Thread by Stephan Br?nnimann | last post: by
2 posts views Thread by Todd Nathan | last post: by
4 posts views Thread by Påhl Melin | last post: by
1 post views Thread by emin.martinian | last post: by
reply views Thread by leo001 | last post: by

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.