By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
424,825 Members | 1,026 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 424,825 IT Pros & Developers. It's quick & easy.

Proposal for adding symbols within Python

P: n/a
Please, note that I am entirely open for every points on this proposal
(which I do not dare yet to call PEP).

Abstract
========

This proposal suggests to add symbols into Python.

Symbols are objects whose representation within the code is more
important than their actual value. Two symbols needs only to be
equally-comparable. Also, symbols need to be hashable to use as keys of
dictionary (symbols are immutable objects).

Motivations
===========

Currently, there is no obvious way to define constants or states or
whatever would be best represented by symbols. Discussions on
comp.lang.python shows at least half a dozen way to replace symbols.

Some use cases for symbols are : state of an object (i.e. for a file
opened/closed/error) and unique objects (i.e. attributes names could be
represented as symbols).

Many languages propose symbols or obvious ways to define symbol-like
values. For examples in common languages:

In C/C++ : Symbols are emulated using Enums.
In Haskell/OCaml : Symbols are defined by union types with empty
constructors. Symbols are local to modules.
In Prolog : Symbols are called atoms ... they are local to modules (at
least in swi-prolog)
In Ruby : Symbols are introduced be the ":" notation. ":open" is a
symbol. Symbols are global.
In LISP : Symbols are introduced by "'". "'open" is a symbol. Symbols
are local to modules.

Proposal
========

First, I think it would be best to have a syntax to represent symbols.
Adding some special char before the name is probably a good way to
achieve that : $open, $close, ... are $ymbols.

On the range of symbols, I think they should be local to name space
(this point should be discussed as I see advantages and drawbacks for
both local and global symbols). For example, for the state of the file
object I would write :
file.$open, file.$close, file.$error
Then, given some other objects (say some other device which also may be
opened) :
assert f.state != dev.state
would always hold if both objects use locally-defined symbols. The only
way for these states to be equal would be, for example, for the device
object to explicitly assign the file symbols :
dev.state = file.$open
By default, symbols should be local to the current module. Then, being
in the module "device_manager", this would hold:
assert $opened == device_manager.$opened
There should be a way to go from strings to symbols and the other way
around. For that purpose, I propose:
assert symbol("opened") == $opened
assert str($opened) == "opened"


Implementation
==============

One possible way to implement symbols is simply with integers resolved
as much as possible at compile time.

The End
=======

Thanks to those who read entirely this proposal and I hope this proposal
will gather enough interests to become a PEP and someday be implemented,
maybe (probably?) in a completely different way ;)

Pierre
Nov 22 '05 #1
Share this Question
Share on Google+
47 Replies


P: n/a
Pierre Barbier de Reuille <pi************@cirad.fr> wrote:
This proposal suggests to add symbols into Python.
I still don't think "symbol" is particularly descriptive as a name;
there are too many other things already in the language that might
also be called a "symbol".
Symbols are objects whose representation within the code is more
important than their actual value.
An interesting
Two symbols needs only to be equally-comparable.
I believe it would be more useful to have enumerated types in Python,
which would also allow values from the same type to be cmp() compared.
Currently, there is no obvious way to define constants or states or
whatever would be best represented by symbols.
"constants" isn't a good equivalent here, since constants in most
other languages are all about the name-to-value mapping, which you
said was unimportant for this concept.
Discussions on comp.lang.python shows at least half a dozen way to
replace symbols.
s/replace/implement/
Some use cases for symbols are : state of an object (i.e. for a file
opened/closed/error) and unique objects (i.e. attributes names could
be represented as symbols).
That pretty much covers the common use cases. Nicely done.
First, I think it would be best to have a syntax to represent
symbols.
I disagree. Namespaces would be fine, and would also make clear which
values were related to each other; e.g. for your "state of an object"
use case, it's useful to have all the states in one namespace,
separate from unrelated states of other classes of objects.
Adding some special char before the name is probably a good way to
achieve that : $open, $close, ... are $ymbols.
Counterproposal:

FileState = SomeTypeDefiningStates( 'open', 'closed' )

thefile.state = FileState.open
if thefile.state == FileState.closed:
print "File is closed"

So all that's needed here is the type SomeTypeDefiningStates, not a
new syntax.
One possible way to implement symbols is simply with integers
resolved as much as possible at compile time.


I believe all your requirements and motivations could be met with an
Enum type in the language. Here's an implementation using a sequence
of integers for the underlying values:

"First Class Enums in Python"
<URL:http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/413486>

An enumerated type would also allow values from that type to be
compared with cmp() if their sequence was considered important. e.g.
for object state, the "normal" sequence of states could be represented
in the enumeration, and individual states compared to see if they are
"later" that each other. If sequence was not considered important, of
course, this feature would not get in the way.

--
\ "I put instant coffee in a microwave oven and almost went back |
`\ in time." -- Steven Wright |
_o__) |
Ben Finney
Nov 22 '05 #2

P: n/a
Pierre Barbier de Reuille <pi************@cirad.fr> writes:
Please, note that I am entirely open for every points on this proposal
(which I do not dare yet to call PEP).

Abstract
========

This proposal suggests to add symbols into Python.
You're also proposing adding a syntax to generate symbols. If so, it's
an important distinction, as simply addig symbols is a lot more
straightforward than adding new syntax.
Symbols are objects whose representation within the code is more
important than their actual value. Two symbols needs only to be
equally-comparable. Also, symbols need to be hashable to use as keys of
dictionary (symbols are immutable objects).
The values returned by object() meet this criteria. You could write
LISPs gensym as:

gensym = object

As you've indicated, there are a number of ways to get such
objects. If all you want is symbols, all that really needs to happen
is that one of those ways be blessed by including an implementation in
the distribution.
In LISP : Symbols are introduced by "'". "'open" is a symbol.
No, they're not. "'(a b c)" is *not* a symbol, it's a list. Symbols in
LISP are just names. "open" is a symbol, but it's normally evaluated.
The "'" is syntax that keeps the next expression from being evaluated,
so that "'open" gets you the symbol rather than it's value. Since
you're trying to introduce syntax, I think it's important to get
existing practice in other languages right.
Proposal
========

First, I think it would be best to have a syntax to represent symbols.
That's half the proposal.
Adding some special char before the name is probably a good way to
achieve that : $open, $close, ... are $ymbols.
$ has bad associations for me - and for others that came from an
earlier P-language. Also, I feel that using a magic character to
introduce type information doesn't feel very Pythonic.

While you don't make it clear, it seems obvious that you intend that
if $open occurs twice in the same scope, it should refer to the same
symbol. So you're using the syntax for a dual purpose. $name checks to
see if the symbol name exists, and references that if so. If not, it
creates a new symbol and with that name. Having something that looks
like a variables that instantiates upon reference instead of raising
an exception seems like a bad idea.
On the range of symbols, I think they should be local to name space
(this point should be discussed as I see advantages and drawbacks for
both local and global symbols).
Agreed. Having one type that has different scoping rules than
everything else is definitely a bad idea.
There should be a way to go from strings to symbols and the other way
around. For that purpose, I propose:
assert symbol("opened") == $opened
assert str($opened) == "opened"

So the heart of your proposal seems to be twofold: The addition of
"symbol" as a type, and the syntax that has the lookup/create behavior
I described above.
Implementation
==============

One possible way to implement symbols is simply with integers resolved
as much as possible at compile time.


What exactly are you proposing be "resolved" at compile time? How is
this better than using object, as illustratd above?

Suggested changes:

Provide a solid definition for the proposed builtin type "symbol".
Something like:

symbol objects support two operations: is and equality
comparison. Two symbol objects compare equal if and only if
they are the same object, and symbol objects never compare
equal to any other type of object. The result of other
operations on a symbol object is undefined, and should raise
a TypeError exception.

symbol([value]) - creates a symbol object. Two distinct
calls to symbol will return two different symbol objects
unless the values passed to them as arguments are equal, in
which case they return the same symbol object. If symbol is
called without an argument, it returns a unique symbol.

I left the type of the value argument unspecified on purpose. Strings
are the obvious type, but I think it should be as unrestricted as
possible. The test on value is equality, not identity, because two
strings can be equal without being the same string, and we want that
case to give us the same symbol. I also added gensym-like behavior,
because it seemed useful. You could do without equality comparison,
but it seems like a nice thing to have.

Now propose a new syntax that "means" symbol, ala {} "meaning" dict
and [] "meaning" list. Don't use "$name" (& and ^ are also probably
bad, but not as; pretty much everything else but ? is already in
use). Python does seem to be moving away from this kind of thing,
though.

Personally, I think that the LISP quote mechanism would be a better
addition as a new syntax, as it would handle needs that have caused a
number of different proposals to be raised. It would require that
symbol know about the internals of the implementation so that ?name
and symbol("name") return the same object, and possibly exposing said
object to the programmer. And this is why the distinction about how
LISP acts is important.

<mike
--
Mike Meyer <mw*@mired.org> http://www.mired.org/home/mwm/
Independent WWW/Perforce/FreeBSD/Unix consultant, email for more information.
Nov 22 '05 #3

P: n/a
On Sat, 12 Nov 2005 16:52:12 -0500, Mike Meyer <mw*@mired.org> wrote:
[...]
Personally, I think that the LISP quote mechanism would be a better
addition as a new syntax, as it would handle needs that have caused a
number of different proposals to be raised. It would require that
symbol know about the internals of the implementation so that ?name
and symbol("name") return the same object, and possibly exposing said
object to the programmer. And this is why the distinction about how
LISP acts is important.

I wonder if the backquote could be deprecated and repurposed.
It could typographically serve nicely as a lisp quote then. But in python,
how would 'whatever be different from lambda:whatever ?
(where of course whatever could be any expression parenthesized
as necessary)

Regards,
Bengt Richter
Nov 22 '05 #4

P: n/a
On Sat, 12 Nov 2005 18:59:39 +0100, Pierre Barbier de Reuille wrote:
First, I think it would be best to have a syntax to represent symbols.
Adding some special char before the name is probably a good way to
achieve that : $open, $close, ... are $ymbols.


I think your chances of convincing Guido to introduce new syntax is slim
to none. (Not quite zero -- he did accept @ for decorators.)

I think symbols should simply be an immutable object, one with state and
limited or no behaviour, rather than a brand new syntactical element.
Being an object, you can reference them in whatever namespace you define
them in.

Personally, I think rather than adding a new language feature (...slim to
none...) there is more hope of getting something like this added to the
standard library:

http://aspn.activestate.com/ASPN/Coo.../Recipe/413486

--
Steven.

Nov 22 '05 #5

P: n/a
Ben Finney a écrit :
Pierre Barbier de Reuille <pi************@cirad.fr> wrote:
This proposal suggests to add symbols into Python.

I still don't think "symbol" is particularly descriptive as a name;
there are too many other things already in the language that might
also be called a "symbol".


Well, that's the name in many languages. Then, probably all the things
already in the language that might be called "symbol" may be implemented
using the symbols in this proposal ... or maybe I don't see what you
mean here ?

[...]
First, I think it would be best to have a syntax to represent
symbols.

I disagree. Namespaces would be fine, and would also make clear which
values were related to each other; e.g. for your "state of an object"
use case, it's useful to have all the states in one namespace,
separate from unrelated states of other classes of objects.

Adding some special char before the name is probably a good way to
achieve that : $open, $close, ... are $ymbols.

Counterproposal:

FileState = SomeTypeDefiningStates( 'open', 'closed' )

thefile.state = FileState.open
if thefile.state == FileState.closed:
print "File is closed"

So all that's needed here is the type SomeTypeDefiningStates, not a
new syntax.


The problem, IMHO, is that way you need to declare "symbols"
beforehands, that's what I was trying to avoid by requiring a new syntax.
One possible way to implement symbols is simply with integers
resolved as much as possible at compile time.

I believe all your requirements and motivations could be met with an
Enum type in the language. Here's an implementation using a sequence
of integers for the underlying values:

"First Class Enums in Python"
<URL:http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/413486>

An enumerated type would also allow values from that type to be
compared with cmp() if their sequence was considered important. e.g.
for object state, the "normal" sequence of states could be represented
in the enumeration, and individual states compared to see if they are
"later" that each other. If sequence was not considered important, of
course, this feature would not get in the way.


Well, I don't think enumarated objects ARE symbols. I can see two
"problems" :
1 - in the implementation, trying to compare values from different
groups raises an error instead of simply returning "False" (easy to fix ...)
2 - You have to declare these enumerable variables, which is not
pythonic IMO (impossible to fix ... needs complete redesign)

In the end, I really think symbols and enum are of different use, one of
the interest un symbols being to let the compiler does what he wants
(i.e. probably what is the most efficient).

Thanks for your reply,

Pierre
Nov 22 '05 #6

P: n/a
Mike Meyer a écrit :
Pierre Barbier de Reuille <pi************@cirad.fr> writes:
Please, note that I am entirely open for every points on this proposal
(which I do not dare yet to call PEP).

Abstract
========
[...]
Symbols are objects whose representation within the code is more
important than their actual value. Two symbols needs only to be
equally-comparable. Also, symbols need to be hashable to use as keys of
dictionary (symbols are immutable objects).

The values returned by object() meet this criteria. You could write
LISPs gensym as:

gensym = object

As you've indicated, there are a number of ways to get such
objects. If all you want is symbols, all that really needs to happen
is that one of those ways be blessed by including an implementation in
the distribution.


Well, I may rewrite the proposal, but one good thing to have is the
hability to go from symbol to string and the opposite (as written below)
and that is not really allowed by this implementation of symbols.

In LISP : Symbols are introduced by "'". "'open" is a symbol.

No, they're not. "'(a b c)" is *not* a symbol, it's a list. Symbols in
LISP are just names. "open" is a symbol, but it's normally evaluated.
The "'" is syntax that keeps the next expression from being evaluated,
so that "'open" gets you the symbol rather than it's value. Since
you're trying to introduce syntax, I think it's important to get
existing practice in other languages right.


You're right ! I was a bit quick here ... "'" is a way to stop
evaluation and you may also write "(quote open)" for "'open".

Proposal
========

First, I think it would be best to have a syntax to represent symbols.

That's half the proposal.

Adding some special char before the name is probably a good way to
achieve that : $open, $close, ... are $ymbols.

$ has bad associations for me - and for others that came from an
earlier P-language. Also, I feel that using a magic character to
introduce type information doesn't feel very Pythonic.

While you don't make it clear, it seems obvious that you intend that
if $open occurs twice in the same scope, it should refer to the same
symbol. So you're using the syntax for a dual purpose. $name checks to
see if the symbol name exists, and references that if so. If not, it
creates a new symbol and with that name. Having something that looks
like a variables that instantiates upon reference instead of raising
an exception seems like a bad idea.


Well, that's why symbols are absolutely not variables. One good model
(IMO) is LISP symbols. Symbols are *values* and equality is not
depending on the way you obtained the symbol :

(eq (quote opened) 'opened)
On the range of symbols, I think they should be local to name space
(this point should be discussed as I see advantages and drawbacks for
both local and global symbols).

Agreed. Having one type that has different scoping rules than
everything else is definitely a bad idea.

There should be a way to go from strings to symbols and the other way
around. For that purpose, I propose:

>assert symbol("opened") == $opened
>assert str($opened) == "opened"

So the heart of your proposal seems to be twofold: The addition of
"symbol" as a type, and the syntax that has the lookup/create behavior
I described above.


Indeed !
Implementation
==============

One possible way to implement symbols is simply with integers resolved
as much as possible at compile time.

What exactly are you proposing be "resolved" at compile time? How is
this better than using object, as illustratd above?

Suggested changes:

Provide a solid definition for the proposed builtin type "symbol".
Something like:

symbol objects support two operations: is and equality
comparison. Two symbol objects compare equal if and only if
they are the same object, and symbol objects never compare
equal to any other type of object. The result of other
operations on a symbol object is undefined, and should raise
a TypeError exception.

symbol([value]) - creates a symbol object. Two distinct
calls to symbol will return two different symbol objects
unless the values passed to them as arguments are equal, in
which case they return the same symbol object. If symbol is
called without an argument, it returns a unique symbol.


Good definition to me !

I left the type of the value argument unspecified on purpose. Strings
are the obvious type, but I think it should be as unrestricted as
possible. The test on value is equality, not identity, because two
strings can be equal without being the same string, and we want that
case to give us the same symbol. I also added gensym-like behavior,
because it seemed useful. You could do without equality comparison,
but it seems like a nice thing to have.
Now propose a new syntax that "means" symbol, ala {} "meaning" dict
and [] "meaning" list. Don't use "$name" (& and ^ are also probably
bad, but not as; pretty much everything else but ? is already in
use). Python does seem to be moving away from this kind of thing,
though.
Well, maybe we should find some other way to express symbols. The only
thing I wanted was a way easy to write, avoiding the need to declare
symbols, and allowing the specification of the scope of the symbol. My
prefered syntax would be something like :

'opened, `opened or `opened`

However, none are usable in current Python.

Personally, I think that the LISP quote mechanism would be a better
addition as a new syntax, as it would handle needs that have caused a
number of different proposals to be raised. It would require that
symbol know about the internals of the implementation so that ?name
and symbol("name") return the same object, and possibly exposing said
object to the programmer. And this is why the distinction about how
LISP acts is important.

<mike


Maybe, although I may say I cannot see clearly how LISP quote mechanism
translates into Python.
Nov 22 '05 #7

P: n/a
Pierre Barbier de Reuille <pi************@cirad.fr> writes:
In LISP : Symbols are introduced by "'". "'open" is a symbol. No, they're not. "'(a b c)" is *not* a symbol, it's a list. Symbols in
LISP are just names. "open" is a symbol, but it's normally evaluated.
The "'" is syntax that keeps the next expression from being evaluated,
so that "'open" gets you the symbol rather than it's value. Since
you're trying to introduce syntax, I think it's important to get
existing practice in other languages right.

You're right ! I was a bit quick here ... "'" is a way to stop
evaluation and you may also write "(quote open)" for "'open".


Yup. Also notice that if you eval the symbol, you get any value that
happens to be bound to it. This is irrelevant for your purposes. But
the properties you're looking for are - in LISP, anyway -
implementation details of how it handles names.
While you don't make it clear, it seems obvious that you intend that
if $open occurs twice in the same scope, it should refer to the same
symbol. So you're using the syntax for a dual purpose. $name checks to
see if the symbol name exists, and references that if so. If not, it
creates a new symbol and with that name. Having something that looks
like a variables that instantiates upon reference instead of raising
an exception seems like a bad idea.


Well, that's why symbols are absolutely not variables.


If they aren't variables, they probably shouldn't *look* like
variables.
Provide a solid definition for the proposed builtin type "symbol".
Something like:

symbol objects support two operations: is and equality
comparison. Two symbol objects compare equal if and only if
they are the same object, and symbol objects never compare
equal to any other type of object. The result of other
operations on a symbol object is undefined, and should raise
a TypeError exception.

symbol([value]) - creates a symbol object. Two distinct
calls to symbol will return two different symbol objects
unless the values passed to them as arguments are equal, in
which case they return the same symbol object. If symbol is
called without an argument, it returns a unique symbol.


Good definition to me !


Note that this definition doesn't capture the name-space semantics you
asked for - symbol(value) is defined to return the same symbol
everywhere it's called, so long as value is equal. This is probably a
good thing. Using the ability to have non-strings for value means you
can get this behavior by passing in something that's unique to the
namespace as part of value. Said something probably depends on the the
flavor of the namespace in question. This allows you to tailor the
namespace choice to your needs.

Also, since I'm allowing non-strings for value, just invoking str on
the symbol isn't really sufficient. Let's add an attribute 'value',
such that symbol(stuff).value is identical to stuff. I you want,
define symbol.__str__ as str(symbol.value) so that str(symbol("foo"))
returns "foo".
Well, maybe we should find some other way to express symbols. The only
thing I wanted was a way easy to write, avoiding the need to declare
symbols, and allowing the specification of the scope of the symbol. My
prefered syntax would be something like :
'opened, `opened or `opened`
However, none are usable in current Python.


Well, symbol('opened') solves the declaration issue, but it's not as
easy as you'd like.
Personally, I think that the LISP quote mechanism would be a better
addition as a new syntax, as it would handle needs that have caused a
number of different proposals to be raised. It would require that
symbol know about the internals of the implementation so that ?name
and symbol("name") return the same object, and possibly exposing said
object to the programmer. And this is why the distinction about how
LISP acts is important.

Maybe, although I may say I cannot see clearly how LISP quote mechanism
translates into Python.


It compiles the quoted expression and returns a code object. I'd love
to recycle backquotes so that `expr` means
compile(expr, 'quoted-expr', 'eval'), but that won't happen anytime soon.

Hmm. You know, $symbol$ doesn't seem nearly as bad as $symbol. It
tickles TeX, not P***. I could live with that.

Like I said, the tricky part of doing this is getting `symbol` to have
the semantics you want. If you compile the same string twice, you get
two different code objects, though they compare equal, and the
variable names in co_names are the same strings. Maybe equality is
sufficient, and you don't need identity.

<mike
--
Mike Meyer <mw*@mired.org> http://www.mired.org/home/mwm/
Independent WWW/Perforce/FreeBSD/Unix consultant, email for more information.
Nov 22 '05 #8

P: n/a
Mike Meyer a écrit :
Pierre Barbier de Reuille <pi************@cirad.fr> writes:
While you don't make it clear, it seems obvious that you intend that
if $open occurs twice in the same scope, it should refer to the same
symbol. So you're using the syntax for a dual purpose. $name checks to
see if the symbol name exists, and references that if so. If not, it
creates a new symbol and with that name. Having something that looks
like a variables that instantiates upon reference instead of raising
an exception seems like a bad idea.
Well, that's why symbols are absolutely not variables.

If they aren't variables, they probably shouldn't *look* like
variables.


Yes, that's why we should find some way to express that.
Provide a solid definition for the proposed builtin type "symbol".
Something like:

symbol objects support two operations: is and equality
comparison. Two symbol objects compare equal if and only if
they are the same object, and symbol objects never compare
equal to any other type of object. The result of other
operations on a symbol object is undefined, and should raise
a TypeError exception.

symbol([value]) - creates a symbol object. Two distinct
calls to symbol will return two different symbol objects
unless the values passed to them as arguments are equal, in
which case they return the same symbol object. If symbol is
called without an argument, it returns a unique symbol.


Good definition to me !

Note that this definition doesn't capture the name-space semantics you
asked for - symbol(value) is defined to return the same symbol
everywhere it's called, so long as value is equal. This is probably a
good thing. Using the ability to have non-strings for value means you
can get this behavior by passing in something that's unique to the
namespace as part of value. Said something probably depends on the the
flavor of the namespace in question. This allows you to tailor the
namespace choice to your needs.


Very interesting ... that way we could get global AND local symbols ...
I like it !

Also, since I'm allowing non-strings for value, just invoking str on
the symbol isn't really sufficient. Let's add an attribute 'value',
such that symbol(stuff).value is identical to stuff. I you want,
define symbol.__str__ as str(symbol.value) so that str(symbol("foo"))
returns "foo".

Well, maybe we should find some other way to express symbols. The only
thing I wanted was a way easy to write, avoiding the need to declare
symbols, and allowing the specification of the scope of the symbol. My
prefered syntax would be something like :
'opened, `opened or `opened`
However, none are usable in current Python.

Well, symbol('opened') solves the declaration issue, but it's not as
easy as you'd like.

Personally, I think that the LISP quote mechanism would be a better
addition as a new syntax, as it would handle needs that have caused a
number of different proposals to be raised. It would require that
symbol know about the internals of the implementation so that ?name
and symbol("name") return the same object, and possibly exposing said
object to the programmer. And this is why the distinction about how
LISP acts is important.


Maybe, although I may say I cannot see clearly how LISP quote mechanism
translates into Python.

It compiles the quoted expression and returns a code object. I'd love
to recycle backquotes so that `expr` means
compile(expr, 'quoted-expr', 'eval'), but that won't happen anytime soon.

Hmm. You know, $symbol$ doesn't seem nearly as bad as $symbol. It
tickles TeX, not P***. I could live with that.


Yep, I like this $symbol$ notation ! It could me equivalent to :

symbol( "symbol" )

And $object.symbol$ could translate into :

symbol( (object, "symbol") )

Like I said, the tricky part of doing this is getting `symbol` to have
the semantics you want. If you compile the same string twice, you get
two different code objects, though they compare equal, and the
variable names in co_names are the same strings. Maybe equality is
sufficient, and you don't need identity.

<mike


Yep, that's something I always found strange but I think this is for
optimization reasons. However, with symbols the problem is quite
different and we can take some time to ensure there are never two same
objects with different ids ... then, we can also garanty only the use of
"==" and not of "is" ...

Pierre
Nov 22 '05 #9

P: n/a
On Sun, 13 Nov 2005 10:11:04 +0100, Pierre Barbier de Reuille wrote:
The problem, IMHO, is that way you need to declare "symbols"
beforehands, that's what I was trying to avoid by requiring a new syntax.
???

If you don't declare your symbols, how will you get the ones that you want?

I don't understand why it is a problem to declare them first, and if it is
a problem, what your solution would be.

[snip]
Well, I don't think enumarated objects ARE symbols. I can see two
"problems" :
1 - in the implementation, trying to compare values from different
groups raises an error instead of simply returning "False" (easy to fix ...)
As you say, that's easy to fix.
2 - You have to declare these enumerable variables, which is not
pythonic IMO (impossible to fix ... needs complete redesign)


Are you suggesting that the Python language designers should somehow
predict every possible symbol that anyone in the world might ever need,
and build them into the language as predefined things?

If that is not what you mean, can you explain please, because I'm confused.

--
Steven.

Nov 22 '05 #10

P: n/a
Steven D'Aprano a écrit :
On Sun, 13 Nov 2005 10:11:04 +0100, Pierre Barbier de Reuille wrote:

The problem, IMHO, is that way you need to declare "symbols"
beforehands, that's what I was trying to avoid by requiring a new syntax.

???

If you don't declare your symbols, how will you get the ones that you want?

I don't understand why it is a problem to declare them first, and if it is
a problem, what your solution would be.


Well, just as Python do not need variable declaration, you can just
*use* them ... in dynamic languages using symbols, they just get created
when used (i.e. have a look at LISP or Ruby).
[snip]

Well, I don't think enumarated objects ARE symbols. I can see two
"problems" :
1 - in the implementation, trying to compare values from different
groups raises an error instead of simply returning "False" (easy to fix ...)

As you say, that's easy to fix.

2 - You have to declare these enumerable variables, which is not
pythonic IMO (impossible to fix ... needs complete redesign)

Are you suggesting that the Python language designers should somehow
predict every possible symbol that anyone in the world might ever need,
and build them into the language as predefined things?

If that is not what you mean, can you explain please, because I'm confused.


Well, the best I can propose is for you to read the discussion with Mike
Meyer.
He pointer out the flaws in my proposal and we're trying to precise things.

Pierre
Nov 22 '05 #11

P: n/a
Steven D'Aprano <st***@removethiscyber.com.au> wrote:
On Sun, 13 Nov 2005 10:11:04 +0100, Pierre Barbier de Reuille wrote:
The problem, IMHO, is that way you need to declare "symbols"
beforehands, that's what I was trying to avoid by requiring a new
syntax.


If you don't declare your symbols, how will you get the ones that
you want?
[...]
Are you suggesting that the Python language designers should somehow
predict every possible symbol that anyone in the world might ever
need, and build them into the language as predefined things?


I believe Pierre is looking for a syntax that will save him from
assigning values to names; that Python will simply assign arbitrary
unique values for these special names. My understanding of the
intended use is that their only purpose is to compare differently to
other objects of the same type, so the actual values don't matter.

What I still don't understand is why this justifies additional syntax
baggage in the language, rather than an explicit assignment earlier in
the code.

--
\ "Smoking cures weight problems. Eventually." -- Steven Wright |
`\ |
_o__) |
Ben Finney
Nov 22 '05 #12

P: n/a
Pierre Barbier de Reuille <pi************@cirad.fr> wrote:
Mike Meyer a écrit :
Hmm. You know, $symbol$ doesn't seem nearly as bad as $symbol. It
tickles TeX, not P***. I could live with that.

Yep, I like this $symbol$ notation !


Gets a big -1 here.

I've yet to see a convincing argument against simply assigning values
to names, then using those names.

--
\ "Yesterday I parked my car in a tow-away zone. When I came back |
`\ the entire area was missing." -- Steven Wright |
_o__) |
Ben Finney
Nov 22 '05 #13

P: n/a
On Sun, 13 Nov 2005 12:33:48 +0100, Pierre Barbier de Reuille wrote:
Steven D'Aprano a écrit :
On Sun, 13 Nov 2005 10:11:04 +0100, Pierre Barbier de Reuille wrote:

The problem, IMHO, is that way you need to declare "symbols"
beforehands, that's what I was trying to avoid by requiring a new syntax.

???

If you don't declare your symbols, how will you get the ones that you want?

I don't understand why it is a problem to declare them first, and if it is
a problem, what your solution would be.


Well, just as Python do not need variable declaration, you can just
*use* them ... in dynamic languages using symbols, they just get created
when used (i.e. have a look at LISP or Ruby).


If you want to be technical, Python doesn't have variables. It has names
and objects.

If I want a name x to be bound to an object 1, I have to define it
(actually bind the name to the object):

x = 1

If I want a symbol $x$ (horrible syntax!!!) with a value 1, why shouldn't
I define it using:

$x$ = 1

instead of expecting Python to somehow magically know that I wanted it?
What if somebody else wanted the symbol $x$ to have the value 2 instead?

[snip]

Well, I don't think enumarated objects ARE symbols. I can see two
"problems" :
1 - in the implementation, trying to compare values from different
groups raises an error instead of simply returning "False" (easy to fix ...)

As you say, that's easy to fix.

2 - You have to declare these enumerable variables, which is not
pythonic IMO (impossible to fix ... needs complete redesign)

Are you suggesting that the Python language designers should somehow
predict every possible symbol that anyone in the world might ever need,
and build them into the language as predefined things?

If that is not what you mean, can you explain please, because I'm confused.


Well, the best I can propose is for you to read the discussion with Mike
Meyer.
He pointer out the flaws in my proposal and we're trying to precise things.


I've read the discussion, and I am no wiser.

You haven't explained why enums are not suitable to be used for symbols.
You gave two "problems", one of which was "easy to fix", as you said
yourself, and the other reason was that you don't want to define enums as
symbols.

If you don't want to define something manually, that can only mean that
you expect them to be predefined. Or am I misunderstanding something?

--
Steven.

Nov 22 '05 #14

P: n/a
Ben Finney a écrit :
Pierre Barbier de Reuille <pi************@cirad.fr> wrote:
Mike Meyer a écrit :
Hmm. You know, $symbol$ doesn't seem nearly as bad as $symbol. It
tickles TeX, not P***. I could live with that.


Yep, I like this $symbol$ notation !

Gets a big -1 here.

I've yet to see a convincing argument against simply assigning values
to names, then using those names.


I can see three interests :
1 - ensure values are unique (i.e. a bit like using instances of object)
2 - values are meaningful (i.e. with introspection on the values you get
a human-readable value, unlike with instances of object)
3 - getting an *easy* access to those two properties

1 and 2 require a new type, 3 a new syntax (IMO).

Here's a try for the symbol class :

class symbol(object):
def __init__(self, value):
self._value = value
def _get_value(self):
return self._value
value = property(_get_value)
def __eq__(self, other):
return self.value == other.value
def __str__(self):
return str(self.value)
def __repr__(self):
return "symbol(%s)" % (repr(self.value),)

One thing to do would be to return the same object for symbols with the
same value (when possible ...).

For example, if we limit symbol to hashable types, we can implement
something which can be tested with "is" instead of "==":

class symbol(object):
_cache = {}
def __new__(cls, value):
if value in symbol._cache:
return symbol._cache[value]
self = object.__new__(cls)
self._value = value
symbol._cache[value] = self
return self
def _get_value(self):
return self._value
value = property(_get_value)
def __eq__(self, other):
return self.value == other.value
def __str__(self):
return str(self.value)
def __repr__(self):
return "symbol(%s)" % (repr(self.value),)

Then, as I suggested, you can do something like :

a = symbol((file, "opened"))

But it's less readable than $file.opened$ (or something similar).

Pierre
Nov 22 '05 #15

P: n/a
Ben Finney <bi****************@benfinney.id.au> writes:
I've yet to see a convincing argument against simply assigning values
to names, then using those names.


The problem with that is that you can't pass around the names of objects
that are used for other things. Obviously they make enums unnecessary,
but only people damaged by non-dynamic languages could think that's the
main point. ;-)

Being able to do that precludes the need for converting going back and
forth between strings and method names when you need to do things like
keeping a list of function names, even when you need to be able to
change what those function names point to.

Python doesn't really need to introduce a new type to do this. It's
already there, as what we usually just call names. Probably this
discussion would benefit from talking about names rather than symbols,
as that seems to confuse some people.

So, Python already has symbols. What we need is a way to refer to these
symbols explicitly. I would suggest to do it like in Lisp:

quote(spam)

Of course, this would preferably be implemented so that it doesn't just
work on simple names:

quote(spam(eggs))

I syntactic sugar, like ' in Lisp, could be introduced later, but I
don't think that would be strictly necessary.

--
Björn Lindström <bk**@stp.lingfil.uu.se>
Student of computational linguistics, Uppsala University, Sweden
Nov 22 '05 #16

P: n/a
On Mon, 14 Nov 2005 00:48:46 +1100, Ben Finney wrote:
Steven D'Aprano <st***@removethiscyber.com.au> wrote:
On Sun, 13 Nov 2005 10:11:04 +0100, Pierre Barbier de Reuille wrote:
> The problem, IMHO, is that way you need to declare "symbols"
> beforehands, that's what I was trying to avoid by requiring a new
> syntax.
If you don't declare your symbols, how will you get the ones that
you want?
[...]
Are you suggesting that the Python language designers should somehow
predict every possible symbol that anyone in the world might ever
need, and build them into the language as predefined things?


I believe Pierre is looking for a syntax that will save him from
assigning values to names; that Python will simply assign arbitrary
unique values for these special names. My understanding of the
intended use is that their only purpose is to compare differently to
other objects of the same type, so the actual values don't matter.


Unless I've misunderstood something, it would be easy to modify the recipe
given here to do something like that:

http://aspn.activestate.com/ASPN/Coo.../Recipe/413486

The example code does this:

Days = Enum('Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa', 'Su')
print Days.Mo, Days.Tu
# etc.

What I still don't understand is why this justifies additional syntax
baggage in the language, rather than an explicit assignment earlier in
the code.


The only advantage would be if you want to do something like this:

MO, TU, WE, TH, FR, SA, SU = Symbols()

and have it magically work. I can see the advantage of that, and you don't
even need new syntax, just a magic function that somehow knows how many
names are on the left hand side of the assignment.

This is a poor substitute:

MO, TU, WE, TH, FR, SA, SU = range(7)

Firstly, if you change the number of symbol names, you have to manually
adjust the argument to range. Secondly, your symbols are actually ints,
and so will compare the same way ints compare.
I don't know enough about the Python internals to tell: is there any
feasible way for there to be a magic function like Symbol above that knew
how many names were waiting for it to be supplied? If there is no way to
do this from Python itself, it is possible to patch the compiler to do so?

--
Steven.

Nov 22 '05 #17

P: n/a
Steven D'Aprano a écrit :
On Sun, 13 Nov 2005 12:33:48 +0100, Pierre Barbier de Reuille wrote:

Steven D'Aprano a écrit :
[...]

If you want to be technical, Python doesn't have variables. It has names
and objects.

If I want a name x to be bound to an object 1, I have to define it
(actually bind the name to the object):

x = 1

If I want a symbol $x$ (horrible syntax!!!) with a value 1, why shouldn't
I define it using:

$x$ = 1

instead of expecting Python to somehow magically know that I wanted it?
What if somebody else wanted the symbol $x$ to have the value 2 instead?


Well, as stated, I don't care about the actual value of symbols. They
*are* values. A trivial implementation of symbols are strings :

$x$ <=> "x"

However, that won't fit because of the scope, because it would be great
to use "is" instead of "==" (even if not necessary), and as said Mike,
you might want something else than a string. That's why `x` would be a
good wawy to write that.

[snip]

I've read the discussion, and I am no wiser.

You haven't explained why enums are not suitable to be used for symbols.
You gave two "problems", one of which was "easy to fix", as you said
yourself, and the other reason was that you don't want to define enums as
symbols.

If you don't want to define something manually, that can only mean that
you expect them to be predefined. Or am I misunderstanding something?


Well, I suspect Python will know them, exactly as it know "without
defining it" that "foo" is the string with chars f, o, o, that 3 is the
number 3, that [1,2] is the list with 1 and 2, ... However, to get
quicker, symbols could be created at compile-time when possible (like
variables). The fact is, symbols allow compilation optimisations that
you cannot get with regular types, because the language is completely
free about their representations. Then, to the programmer it is a good
way to have a meaningful value without caring about how to represent it
in the computer. That way, while debugging, if I ask the value of
file.state I will get something I can read instead of some meaningless
integer or other anonymous object.

So I gain in readability of my code and in debugging capacity.

Pierre
Nov 22 '05 #18

P: n/a
Björn Lindström a écrit :
Ben Finney <bi****************@benfinney.id.au> writes:

I've yet to see a convincing argument against simply assigning values
to names, then using those names.

The problem with that is that you can't pass around the names of objects
that are used for other things. Obviously they make enums unnecessary,
but only people damaged by non-dynamic languages could think that's the
main point. ;-)

Being able to do that precludes the need for converting going back and
forth between strings and method names when you need to do things like
keeping a list of function names, even when you need to be able to
change what those function names point to.

Python doesn't really need to introduce a new type to do this. It's
already there, as what we usually just call names. Probably this
discussion would benefit from talking about names rather than symbols,
as that seems to confuse some people.

So, Python already has symbols. What we need is a way to refer to these
symbols explicitly. I would suggest to do it like in Lisp:

quote(spam)

Of course, this would preferably be implemented so that it doesn't just
work on simple names:

quote(spam(eggs))

I syntactic sugar, like ' in Lisp, could be introduced later, but I
don't think that would be strictly necessary.


Well, if this already exists in Python's internals, then, it would be
great just to expose them. Now, just being able to write :
quote(spam)

quote(spam)

requires a new syntax so that spam is not resolved *before* calling the
quote method.

Pierre
Nov 22 '05 #19

P: n/a
Ben Finney wrote:
....
I've yet to see a convincing argument against simply assigning values
to names, then using those names.


I don't like any syntax I've seen so far, but I can understand the problem.
If you have a name, you can redefine a name, therefore the value a name
refers to is mutable. As a result if you have 2 symbols represented by
names and values, you may have two symbols with different names but the
same value. Hence the two "symbols" are no longer unique)

Conversely consider "NAME" to be a symbol. I can't modify "NAME". It always
means the same as "NAME" and "NAME", but is never the same as "FRED".
What's tricky is I can't have namespaceOne."NAME" [1] and
namespaceTwo."NAME" as different "NAME"s even though logically there's no
reason I couldn't treat "NAME" differently inside each.

[1] Supposing for a moment that I could have a string as a name in a
namespace. (Rather than a string used as a key in that namespace)

However it might be useful to note that these two values (or symbols) are
actually different, even if you remove their namespaces.

To me, the use of a symbol implies a desire for a constant, and then to only
use that constant rather than the value. In certain situations it's the
fact that constant A is not the same as constant B that's important (eg
modelling state machines).

Often you can use strings for that sort of thing, but unfortunately even
python's strings can't be used as symbols that are always the same thing
in all ways. For example, we can force the id of identical strings to be
different:
s = "h"*10000
x = "h"*10000
id(s), id(x)

(135049832, 135059864)

As a result I can see that *IF* you really want this kind of symbol, rather
than the various other kinds people have discussed in the thread, that some
special syntax (like u'hello' for unicode 'hello') could be useful.

However, I'd be more interested in some real world usecases where this would
be beneficial, and then seeing what sort of syntax would be nice/useful
(Especially since I can think of some uses where it would be nice).

On the original syntax proposal, I'm firmly in the -1 camp - to me having
done lots of perl in the past $foo looks very firmly like a mutable, rather
than an immutable.

The reason I'm more interested in seeing usecases, is because I'd rather see
where the existing approaches people use/define symbols has caused the OP
problems to the extent he feels the language needs to change to fix these
real world problems.
Michael.

Nov 22 '05 #20

P: n/a
Steven D'Aprano <st***@removethiscyber.com.au> wrote:
On Mon, 14 Nov 2005 00:48:46 +1100, Ben Finney wrote:
I believe Pierre is looking for a syntax that will save him from
assigning values to names; that Python will simply assign
arbitrary unique values for these special names.

What I still don't understand is why this justifies additional
syntax baggage in the language, rather than an explicit assignment
earlier in the code.


The only advantage would be if you want to do something like this:

MO, TU, WE, TH, FR, SA, SU = Symbols()


I believe that's exactly what Pierre doesn't want to do. He wants to
simply use names (marked special in some way) and have Python
automatically determine a unique value for each name, with nary an
assignment in sight.

To me, that's a net loss. It makes names more complicated, it loses
"explicit is better than implicit", and it loses the checks Python
could do against using a name that hasn't been assigned a value
(caused by e.g. a misspelled name).

--
\ "Why should I care about posterity? What's posterity ever done |
`\ for me?" -- Groucho Marx |
_o__) |
Ben Finney
Nov 22 '05 #21

P: n/a
Ben Finney wrote:
I believe that's exactly what Pierre doesn't want to do. He wants to
simply use names (marked special in some way) and have Python
automatically determine a unique value for each name, with nary an
assignment in sight.

To me, that's a net loss. It makes names more complicated, it loses
"explicit is better than implicit", and it loses the checks Python
could do against using a name that hasn't been assigned a value
(caused by e.g. a misspelled name).


I agree. And, when done explicitly, it's already easy enough to do this
within the language, by just assigning it a value, even if it's an
integer from range/xrange or a new sentinel like object().

--
Erik Max Francis && ma*@alcyone.com && http://www.alcyone.com/max/
San Jose, CA, USA && 37 20 N 121 53 W && AIM erikmaxfrancis
The stairs of the sky are let down for him that he may ascend thereon
to heaven. O gods, put your arms under the king: raise him, lift him
Nov 22 '05 #22

P: n/a
Michael <ms@cerenity.org> wrote:
Ben Finney wrote:
I've yet to see a convincing argument against simply assigning
values to names, then using those names.
If you have a name, you can redefine a name, therefore the value a
name refers to is mutable.


Since there are mutable and immutable values, it might be clearer to
say "the binding of a name to a value can be changed". Yes?

In that case, I don't see why someone who wants such a binding to be
unchanging can't simply avoid changing it. Where's the case for having
Python enforce this?
Conversely consider "NAME" to be a symbol. I can't modify "NAME". It
always means the same as "NAME" and "NAME", but is never the same as
"FRED". What's tricky is I can't have namespaceOne."NAME" [1] and
namespaceTwo."NAME" as different "NAME"s even though logically
there's no reason I couldn't treat "NAME" differently inside each.
So you want to mark such objects as being in a namespace, where they
compare the same within that namespace but not outside. Why is
separate syntax necessary for this? A data type that is informed of
its "space", and refuses comparison with values from other spaces,
would suffice.

class Xenophobe(object):
def __init__(self, space, value):
self.__space = space
self.__value = value

def __str__(self):
return str(self.__value)

def __cmp__(self, other):
if not isinstance(other, Xenophobe):
raise AssertionError, \
"Can only compare Xenophobes to each other"
if not other.__space == self.__space:
raise AssertionError, \
"Can only compare Xenophobes from the same space"
return cmp(self.__value, other.__value)

With the bonus that you could pass such values around between
different names, and they'd *still* compare, or not, as you choose
when you first create them.

Replace the AssertionError with some appropriate return value, if you
want such comparisons to succeed.
However it might be useful to note that these two values (or
symbols) are actually different, even if you remove their
namespaces.
The above Xenophobe implementation creates objects that know their
"space" forever.
To me, the use of a symbol implies a desire for a constant, and then
to only use that constant rather than the value. In certain
situations it's the fact that constant A is not the same as constant
B that's important (eg modelling state machines).
Since the actual value can't be easily accessed, the only purpose of a
Xenophobe is too be created and compared to others.
Often you can use strings for that sort of thing, but unfortunately
even python's strings can't be used as symbols that are always the
same thing in all ways. For example, we can force the id of
identical strings to be different:
Hold up -- what in your stated use case requires *identity* to be the
same? You said you just wanted to compare them to each other.

Besides, Python *does* preserve identity for short strings...
s = "h"*10000
x = "h"*10000
id(s), id(x)

(135049832, 135059864)


.... which is sufficient for unique values, if you're not actively
fighting the system as above. If the use case is for brief, identical
values, we have those: short strings.
As a result I can see that *IF* you really want this kind of symbol,
rather than the various other kinds people have discussed in the
thread, that some special syntax (like u'hello' for unicode 'hello')
could be useful.
I can see the case for a new type. I disagree that syntax changes are
necessary.
However, I'd be more interested in some real world usecases where
this would be beneficial, and then seeing what sort of syntax would
be nice/useful (Especially since I can think of some uses where it
would be nice).
Real use cases would interest me, too, but *only* if they can't be
satisfied with a new type that knows things about its creation state,
such as Xenophobe.
The reason I'm more interested in seeing usecases, is because I'd
rather see where the existing approaches people use/define symbols
has caused the OP problems to the extent he feels the language needs
to change to fix these real world problems.


Ditto.

--
\ "My aunt gave me a walkie-talkie for my birthday. She says if |
`\ I'm good, she'll give me the other one next year." -- Steven |
_o__) Wright |
Ben Finney
Nov 22 '05 #23

P: n/a
Ben Finney a écrit :
Michael <ms@cerenity.org> wrote:
Ben Finney wrote:
I've yet to see a convincing argument against simply assigning
values to names, then using those names.
If you have a name, you can redefine a name, therefore the value a
name refers to is mutable.

Since there are mutable and immutable values, it might be clearer to
say "the binding of a name to a value can be changed". Yes?

In that case, I don't see why someone who wants such a binding to be
unchanging can't simply avoid changing it. Where's the case for having
Python enforce this?


The problem is not about having something constant !
The main point with symbols is to get human-readable values.
Let say you have a symbol "opened" and a symbol "closed". The state of a
file may be one of the two.

If you have these symbols, you can ask for the state at any point and
get something readable. If you use constants valued, typically, to
integers, the state of your file will we 0 or 1, which does not mean
anything.

Now, if you're using an object with more than two states, and moreover
if the number of states is likely to increase during developpement, it's
much more convenient to directly get the *meaning* of the value rather
than the value itself (which does not mean anything).

The key point that, I think, you misunderstand is that symbols are not
*variables* they are *values*.
Conversely consider "NAME" to be a symbol. I can't modify "NAME". It
always means the same as "NAME" and "NAME", but is never the same as
"FRED". What's tricky is I can't have namespaceOne."NAME" [1] and
namespaceTwo."NAME" as different "NAME"s even though logically
there's no reason I couldn't treat "NAME" differently inside each.

So you want to mark such objects as being in a namespace, where they
compare the same within that namespace but not outside. Why is
separate syntax necessary for this? A data type that is informed of
its "space", and refuses comparison with values from other spaces,
would suffice.

class Xenophobe(object):
def __init__(self, space, value):
self.__space = space
self.__value = value

def __str__(self):
return str(self.__value)

def __cmp__(self, other):
if not isinstance(other, Xenophobe):
raise AssertionError, \
"Can only compare Xenophobes to each other"
if not other.__space == self.__space:
raise AssertionError, \
"Can only compare Xenophobes from the same space"
return cmp(self.__value, other.__value)

With the bonus that you could pass such values around between
different names, and they'd *still* compare, or not, as you choose
when you first create them.

Replace the AssertionError with some appropriate return value, if you
want such comparisons to succeed.


Well, I think a new syntax will promote the use of symbols. And as I
think they are good practice (much better than meaningless constants)
they should be promoted. Needless to say that in every language I know
implementing symbols (or something close to symbols), there is an
easy-to-use syntax associated.
However it might be useful to note that these two values (or
symbols) are actually different, even if you remove their
namespaces.

The above Xenophobe implementation creates objects that know their
"space" forever.

To me, the use of a symbol implies a desire for a constant, and then
to only use that constant rather than the value. In certain
situations it's the fact that constant A is not the same as constant
B that's important (eg modelling state machines).

Since the actual value can't be easily accessed, the only purpose of a
Xenophobe is too be created and compared to others.

Often you can use strings for that sort of thing, but unfortunately
even python's strings can't be used as symbols that are always the
same thing in all ways. For example, we can force the id of
identical strings to be different:

Hold up -- what in your stated use case requires *identity* to be the
same? You said you just wanted to compare them to each other.

Besides, Python *does* preserve identity for short strings...

>s = "h"*10000
>x = "h"*10000
>id(s), id(x)


(135049832, 135059864)

... which is sufficient for unique values, if you're not actively
fighting the system as above. If the use case is for brief, identical
values, we have those: short strings.


Well, one *big* difference between short string and symbols is that the
identity between short strings are implementation dependant, while
between symbols it has to be in all implementations as you will rely on
this identity. Then, once more, strings are just one possible
implementation for symbols and I wouldn't like to tie that much symbols
to strings.
As a result I can see that *IF* you really want this kind of symbol,
rather than the various other kinds people have discussed in the
thread, that some special syntax (like u'hello' for unicode 'hello')
could be useful.

I can see the case for a new type. I disagree that syntax changes are
necessary.


Well, syntactic sugar is all about what you want to promote or
discourage ... it is never necessary, even if it can really be usefull.
However, I'd be more interested in some real world usecases where
this would be beneficial, and then seeing what sort of syntax would
be nice/useful (Especially since I can think of some uses where it
would be nice).

Real use cases would interest me, too, but *only* if they can't be
satisfied with a new type that knows things about its creation state,
such as Xenophobe.


Well, once more, new syntax for new objects never solve new problems,
they just make them easier to write.
The reason I'm more interested in seeing usecases, is because I'd
rather see where the existing approaches people use/define symbols
has caused the OP problems to the extent he feels the language needs
to change to fix these real world problems.

Ditto.


Pierre
Nov 22 '05 #24

P: n/a
Pierre Barbier de Reuille wrote:
Please, note that I am entirely open for every points on this proposal
(which I do not dare yet to call PEP).


I still don't see why you can't just use strings. The only two issues I
see you might have with them are a) two identical strings might not be
identical by id(), b) they aren't local in scope.

The objection a) is minor. One, all of your examples use equality for
testing already, and two, short strings are interned and identical in
most cases anyway (they only differ if you go to lengths to create
them, or they aren't sufficiently "variable like") - at most you would
have to standardize the rules.

The objection b) is a little harder to dismiss. But I'm not sure if
you've completely thought what it means for a symbol to be "local to a
module". What happens when you assign a variable containing a symbol to
a variable in another module? For that matter, what does it mean to be
"in a module". Which module is a class instance (and associated sybols)
"in" if the class is defined in one module, instantiated in another, and
then passed as a return value to a third? What about from ... imports?
If you need a symbol "from another class" what's the mechanism of
obtaining it? Can you import symbols? Since you advocate storing symbols
internally as integers, I suppose you would have a program-global table
to keep symbols from different modules from having the same internal
representation. How do you pickle a symbol and have it go to a different
Python program, which may have a massive symbol table of it's own?
It's been said before, and I'll say it again - the key to successful
Python language changes is compelling use cases. Find an existing Python
program or library (the stdlib is best) which would be markedly improved
by your language change. Not only will Guido be more likely to be
convinced, but what you're proposing will likely be clearer to everyone
else, if it's grounded in practical use cases.
Nov 22 '05 #25

P: n/a
Rocco Moretti wrote:
Pierre Barbier de Reuille wrote:
Please, note that I am entirely open for every points on this proposal
(which I do not dare yet to call PEP).


I still don't see why you can't just use strings.


As does Guido.

Reinhold
Nov 22 '05 #26

P: n/a
Pierre Barbier de Reuille <pierre_dot_barbier@_nospam_cirad.fr> wrote:
The problem is not about having something constant !
The main point with symbols is to get human-readable values.
Let say you have a symbol "opened" and a symbol "closed". The state
of a file may be one of the two.
from some_enum_module import Enum

FileState = Enum('open', 'closed')

input_file.state = FileState.closed
If you have these symbols, you can ask for the state at any point
and get something readable. If you use constants valued, typically,
to integers, the state of your file will we 0 or 1, which does not
mean anything.
str(input_file.state) # -> 'closed'
Now, if you're using an object with more than two states, and
moreover if the number of states is likely to increase during
developpement, it's much more convenient to directly get the
*meaning* of the value rather than the value itself (which does not
mean anything).
PixelColour = Enum('red', 'green', 'blue', 'black')
The key point that, I think, you misunderstand is that symbols are
not *variables* they are *values*.
So far, I see nothing that requires anything but a special object type
with the behaviour you describe. Which most of the enumerated-type
implementations do quite neatly.
Well, once more, new syntax for new objects never solve new
problems, they just make them easier to write.


If you want to promote something, it would be best to implement it and
demonstrate some problems that it solves. You don't seem to be arguing
against a new object type, so perhaps it would be best to simply start
using that type to solve some actual problems.

Since "promotion" is the only argument you've given for new syntax
for this concept, I don't see what is served talking about creating
syntax for something that does not yet exist to be promoted. Once an
implementation exists for examination and is actually useful to some
amount of users for solving actual problems, that's the time to talk
about promoting it.

--
\ "I went to the cinema, it said 'Adults: $5.00, Children $2.50'. |
`\ So I said 'Give me two boys and a girl.'" -- Steven Wright |
_o__) |
Ben Finney
Nov 22 '05 #27

P: n/a
On Mon, 14 Nov 2005 17:15:04 +0100, Pierre Barbier de Reuille wrote:
The problem is not about having something constant !
The main point with symbols is to get human-readable values.
Let say you have a symbol "opened" and a symbol "closed". The state of a
file may be one of the two.

If you have these symbols, you can ask for the state at any point and
get something readable. If you use constants valued, typically, to
integers, the state of your file will we 0 or 1, which does not mean
anything.
???

Why does the byte string "\x6f\x70\x65\x6e\x65\x64" have intrinsic meaning
when the int 0 doesn't? It certainly doesn't mean anything to non-English
speakers.

If all you want is human readable byte strings, then just use them:

class MyFile:
def open(self):
self.state = "opened"
def close(self):
self.state = "closed"
You don't need special syntax to use strings as symbols, you get them for
free without all the overhead you are proposing.

Now, if you're using an object with more than two states, and moreover
if the number of states is likely to increase during developpement, it's
much more convenient to directly get the *meaning* of the value rather
than the value itself (which does not mean anything).
How do you expect this to work in practice? You have an object which
has states:

obj = SomeThingComplex()

Now you want to operate on it according to the state. What do you do?

if obj.state is $closed$:
obj.open()
elif obj.state is $opened$:
obj.close()
elif obj.state is $full$:
obj.make_empty()
elif obj.state is $empty$:
obj.make_full()
else:
# some other symbol
raise ValueError("Unexpected state %s") % obj.state

Replace "is" with "==" and $ with " and you have strings. You still need
to know what the object state is, and the way you do that is by comparing
it to something. Whether you call that something a symbol, an enum, a
string, an int, a class, whatever, the comparison still needs to be done.

The key point that, I think, you misunderstand is that symbols are not
*variables* they are *values*.
Python doesn't have variables. It has names and objects.

Well, I think a new syntax will promote the use of symbols. And as I
think they are good practice (much better than meaningless constants)
they should be promoted. Needless to say that in every language I know
implementing symbols (or something close to symbols), there is an
easy-to-use syntax associated.
Why is $closed$ better practice than "closed"?

Why is "closed" a meaningless constant and $closed$ a good symbol?

Well, one *big* difference between short string and symbols is that the
identity between short strings are implementation dependant,
Then don't use identity. Who cares whether the state you are testing
against points to the same chunk of memory or not? What possible
difference will that make, except some unnecessary optimization
_possibly_ saving you one millionth of a second at runtime?
while
between symbols it has to be in all implementations as you will rely on
this identity. Then, once more, strings are just one possible
implementation for symbols and I wouldn't like to tie that much symbols
to strings.


And ints are another possible implementation for symbols, or classes, or
enums.

obj.state = 42 is not an ideal implementation, because it is not
self-documenting, and self-documenting code is good code. But in some
contexts, it may be the right thing to do:

class MutablePolygon:
"""Define a polygon object that can grow or lose sides."""
def __init__(self, n):
"""Create a new polygon with n sides."""
self.state = n
def grow_side(self):
self.state += 1
def lose_side(self):
self.state -= 1

Compare that with something like this:

class MutablePolygon:
"""Define a polygon object that can grow or lose sides."""
def __init__(self, n):
"""Create a new polygon with n sides."""
if n == 1:
self.state = $one$
elif n == 2:
self.state = $two$
elif n == 3:
self.state = $three$
elif n ...
--
Steven.

Nov 22 '05 #28

P: n/a
On 2005-11-14, Rocco Moretti <ro**********@hotpop.com> wrote:
Please, note that I am entirely open for every points on this proposal
(which I do not dare yet to call PEP).
I still don't see why you can't just use strings.


Same here. In the situations described, I always use strings
and have never felt the need for something else:

file.state = 'closed'

...

if file.state == 'open':
whatever
elif file.state == 'error':
something_else

The only two issues I see you might have with them are a) two
identical strings might not be identical by id(), b) they
aren't local in scope.

The objection a) is minor. [...]
The objection b) is a little harder to dismiss. But I'm not
sure if you've completely thought what it means for a symbol
to be "local to a module".


I don't think I even understand what the objection is. What is
needed is a code fragment that shows how the use of strings is
untenable.

--
Grant Edwards grante Yow! And furthermore,
at my bowling average is
visi.com unimpeachable!!!
Nov 22 '05 #29

P: n/a
Steven D'Aprano <st***@REMOVETHIScyber.com.au> writes:
Why does the byte string "\x6f\x70\x65\x6e\x65\x64" have intrinsic
meaning when the int 0 doesn't? It certainly doesn't mean anything to
non-English speakers.

If all you want is human readable byte strings, then just use them:

class MyFile:
def open(self):
self.state = "opened"
def close(self):
self.state = "closed"


So, I guess no one read my explanation of why this an issue about more
than implementing enums (which is fairly trivial, as we have seen).

--
Björn Lindström <bk**@stp.lingfil.uu.se>
Student of computational linguistics, Uppsala University, Sweden
Nov 22 '05 #30

P: n/a
Björn Lindström wrote:
So, I guess no one read my explanation of why this an issue about more
than implementing enums (which is fairly trivial, as we have seen).

I read it. I don't see that it is an issue, and I
especially don't see why it is relevent to Pierre's
usage of symbols.

In your earlier post, you say:

"The problem with that is that you can't pass around
the names of objects that are used for other things."

That's demonstrably not true. If you know that the name
of something is Parrot, then you can pass the string
"Parrot" and use it in many ways:

print obj.__getattribute__["Parrot"]
instance.__dict__["Parrot"] = 42

I'm not aware of anything that you can do to a
name/object binding that can't also be done by a
string. Perhaps I've missed something -- anyone?

If you don't know the name, well, how did it get into
your program in the first case? Where did it come from?
If it came from user input, then surely that is a
string, yes?

You also suggested:

"Being able to do that precludes the need for
converting going back and forth between strings and
method names when you need to do things like keeping a
list of function names, even when you need to be able
to change what those function names point to."

I'm not convinced. Instead of keeping a list of
function names, just keep a list of functions --
functions are first-class objects in Python.

If you need to change what the function names point to,
simply rebind the list item to another function.

The only benefit I can see for being able to refer to
functions by name would be if you are writing a formula
evaluator, it might be useful to have "sin"(0) evaluate
directly. But I don't like the idea of making strings
aliases to executables, except through a single
well-understood mechanism. I'd much rather accept one
intermediate layer than create a second mechanism of
function execution:

table = {"sin": math.sin, "cos": math.cos}
# easy to modify
table["sin"] = my_better_sine_function
result = table["sin"](0)
If I have missed a usage case, perhaps you should give
at specific example.
--
Steven.

Nov 22 '05 #31

P: n/a
Steven D'Aprano <st***@removethiscyber.com.au> wrote:
On Mon, 14 Nov 2005 17:15:04 +0100, Pierre Barbier de Reuille wrote:
The key point that, I think, you misunderstand is that symbols are
not *variables* they are *values*.


Python doesn't have variables. It has names and objects.


That seems to be what Pierre wants to change.

What he hasn't yet made clear is what benefit this brings, over simply
using existing basic types (with as much intrinsic meaning -- i.e.
none -- as the new object he's proposing).

--
\ "I cannot conceive that anybody will require multiplications at |
`\ the rate of 40,000 or even 4,000 per hour ..." -- F. H. Wales |
_o__) (1936) |
Ben Finney
Nov 22 '05 #32

P: n/a
Björn Lindström <bk**@stp.lingfil.uu.se> wrote:
So, I guess no one read my explanation of why this an issue about
more than implementing enums (which is fairly trivial, as we have
seen).


I read it. I see that something more than enums is being asked for.
What I don't see is a use case where this is a benefit over just using
an object type, such as enum or a string or something else.

--
\ "All my life I've had one dream: to achieve my many goals." -- |
`\ Homer, _The Simpsons_ |
_o__) |
Ben Finney
Nov 22 '05 #33

P: n/a
Grant Edwards wrote:
In the situations described, I always use strings
and have never felt the need for something else:
....
I don't think I even understand what the objection is. What is
needed is a code fragment that shows how the use of strings is
untenable.


myObject.value = 'value1'

#... 100 lines of code elided...

if myObject.value = 'Value1':
do_right_thing()
else:
do_wrong_thing()
I don't actually think string use is 'untenable', but it is definitely
more error-prone. With some sort of named object on the right hand side
you will at least get a helpful NameError.

--
Ben Sizer.

Nov 22 '05 #34

P: n/a
On Tue, 15 Nov 2005 01:57:53 -0800, Ben Sizer wrote:
I don't think I even understand what the objection is. What is
needed is a code fragment that shows how the use of strings is
untenable.


myObject.value = 'value1'

#... 100 lines of code elided...

if myObject.value = 'Value1':
do_right_thing()
else:
do_wrong_thing()
I don't actually think string use is 'untenable', but it is definitely
more error-prone. With some sort of named object on the right hand side
you will at least get a helpful NameError.


It is moments like this that I'm not too proud to admit I learnt some good
techniques from Pascal:

# define some pseudo-constants
RIGHT_THING = 'value1'
WRONG_THING = 'some other value'
INCHES_TO_FEET = 12
CM_TO_METRES = 100

# ...

myObject.value = RIGHT_THING

#... 100 lines of code elided...

if myObject.value = RIGHT_THING:
do_right_thing()
else:
do_wrong_thing()
It isn't always appropriate or necessary to define "constants" (and I
sometimes wish that Python would enforce assign-once names), but they can
help avoid some silly mistakes.

--
Steven.

Nov 22 '05 #35

P: n/a
On 2005-11-15, Ben Sizer <ky*****@gmail.com> wrote:
Grant Edwards wrote:
In the situations described, I always use strings
and have never felt the need for something else:


...
I don't think I even understand what the objection is. What is
needed is a code fragment that shows how the use of strings is
untenable.


myObject.value = 'value1'

#... 100 lines of code elided...

if myObject.value == 'Value1':
do_right_thing()
else:
do_wrong_thing()

I don't actually think string use is 'untenable', but it is
definitely more error-prone. With some sort of named object on
the right hand side you will at least get a helpful NameError.


I don't see how that's an argument in favor of the proposal
being discussed. Aren't $Value1 and $value1 both legal and
distinct symbols in the proposed syntax? Won't you have the
exact same issue that you do with mis-typing strings?

--
Grant Edwards grante Yow! .. Do you like
at "TENDER VITTLES?"?
visi.com
Nov 22 '05 #36

P: n/a
Björn Lindström wrote:
Steven D'Aprano <st***@REMOVETHIScyber.com.au> writes:

Why does the byte string "\x6f\x70\x65\x6e\x65\x64" have intrinsic
meaning when the int 0 doesn't? It certainly doesn't mean anything to
non-English speakers.

If all you want is human readable byte strings, then just use them:

class MyFile:
def open(self):
self.state = "opened"
def close(self):
self.state = "closed"

So, I guess no one read my explanation of why this an issue about more
than implementing enums (which is fairly trivial, as we have seen).


I did, but I still don't see why it is an argument against using
strings. The point you may not appreciate is that (C)Python already uses
strings to represent names, as an important part of its introspective
abilities.

##########################################
import dis
def f(): module.klass.method()

dis.dis(f) 2 0 LOAD_GLOBAL 0 (module)
3 LOAD_ATTR 1 (klass)
6 LOAD_ATTR 2 (method)
9 CALL_FUNCTION 0
12 POP_TOP
13 LOAD_CONST 0 (None)
16 RETURN_VALUE f.func_code.co_names ('module', 'klass', 'method') type(f.func_code.co_names[1]) is type('a') True
##############################################

I'll let you dig through the interpreter source to convince yourself
that, indeed, the names module, klass, and method are stored internally
as true python strings. The same holds for other namespaces - the names
are stored as real python strings, in a real python dictionary.

############################################ class c: def foo(self):
pass
def bar(self):
pass
def baz(self):
pass

type(c.__dict__) is type({}) True c.__dict__.keys() ['baz', '__module__', 'foo', 'bar', '__doc__'] type(c.__dict__.keys()[0]) is type('a')

True
##############################################

P.S. This may change for other implementations of Python, but the fact
remains - there is less difference between names and strings than you
may first think.
Nov 22 '05 #37

P: n/a
On Tue, 15 Nov 2005 21:53:23 +1100, Steven D'Aprano <st***@REMOVETHIScyber.com.au> wrote:
[...]
It isn't always appropriate or necessary to define "constants" (and I
sometimes wish that Python would enforce assign-once names), but they can
help avoid some silly mistakes.

(As I'm sure you know) you can have "assign-once" names
if you are willing to spell them with a dot ;-)
N = type('',(),{'name':property(lambda _:42)})()
N.name 42 N.name = 43

Traceback (most recent call last):
File "<stdin>", line 1, in ?
AttributeError: can't set attribute

One could also write a more efficient write-once guarantee for function scope
using a decorator that munges byte code to guarantee it.

Or one could write a custom import that guarantees it for module scope.

Or one could change the language ;-)

Regards,
Bengt Richter
Nov 22 '05 #38

P: n/a
Rocco Moretti a écrit :
[...]


I did, but I still don't see why it is an argument against using
strings. The point you may not appreciate is that (C)Python already uses
strings to represent names, as an important part of its introspective
abilities.


Well, I'm well aware of that, but I'm also well aware that's (as you
said yourself) specific to C-Python, so can just *cannot* rely on
strings being used as symbols in the language. What I would like to see
in Python is "names" (or "symbols", as you prefer) defined within the
language so that you'll get something similar in whatever Python
implementation.

Then, in CPython, names may well be just strings are they already are
implemented to be efficient as such, but other implementation may just
choose something completly different.

The point is, why don't provide the programmer to express just what he
needs (that is, some symbolic value like "opened", "blocked", ...) and
let the interpreter use whatever he think is more efficient for him ?

That's the whole points for "names" ... being able to handle symbolic
values within the language, that's what made LISP so successful. That's
what makes dynamic languages possible ! But why say a name is a
*string* when it is just an implementation detail ??? Isn't Python
mainly about allowing the programmer to concentrate on important stuff ?

Pierre
Nov 22 '05 #39

P: n/a
Rocco Moretti a écrit :
[...]


I did, but I still don't see why it is an argument against using
strings. The point you may not appreciate is that (C)Python already uses
strings to represent names, as an important part of its introspective
abilities.


Well, I'm well aware of that, but I'm also well aware that's (as you
said yourself) specific to C-Python, so can just *cannot* rely on
strings being used as symbols in the language. What I would like to see
in Python is "names" (or "symbols", as you prefer) defined within the
language so that you'll get something similar in whatever Python
implementation.

Then, in CPython, names may well be just strings are they already are
implemented to be efficient as such, but other implementation may just
choose something completly different.

The point is, why don't provide the programmer to express just what he
needs (that is, some symbolic value like "opened", "blocked", ...) and
let the interpreter use whatever he think is more efficient for him ?

That's the whole points for "names" ... being able to handle symbolic
values within the language, that's what made LISP so successful. That's
what makes dynamic languages possible ! But why say a name is a
*string* when it is just an implementation detail ??? Isn't Python
mainly about allowing the programmer to concentrate on important stuff ?

Pierre
Nov 22 '05 #40

P: n/a
Grant Edwards wrote:
On 2005-11-15, Ben Sizer <ky*****@gmail.com> wrote:

myObject.value = 'value1'

#... 100 lines of code elided...

if myObject.value == 'Value1':
do_right_thing()
else:
do_wrong_thing()

I don't actually think string use is 'untenable', but it is
definitely more error-prone. With some sort of named object on
the right hand side you will at least get a helpful NameError.


I don't see how that's an argument in favor of the proposal
being discussed. Aren't $Value1 and $value1 both legal and
distinct symbols in the proposed syntax? Won't you have the
exact same issue that you do with mis-typing strings?


I think the idea is that if the symbol hasn't been instantiated locally
in an assignment operation, then it will not exist, and "if foo ==
$symbolName" will either raise a NameError or flag some error during
compilation. It cannot do this with string comparisons.

I expect this would require a 2-pass compilation process, the first
pass spotting all references to symbols and instantiating them
appropriately, the second pass resolving these references and noting
any that did not match up.

--
Ben Sizer

Nov 22 '05 #41

P: n/a
Grant Edwards wrote:
On 2005-11-15, Ben Sizer <ky*****@gmail.com> wrote:

myObject.value = 'value1'

#... 100 lines of code elided...

if myObject.value == 'Value1':
do_right_thing()
else:
do_wrong_thing()

I don't actually think string use is 'untenable', but it is
definitely more error-prone. With some sort of named object on
the right hand side you will at least get a helpful NameError.


I don't see how that's an argument in favor of the proposal
being discussed. Aren't $Value1 and $value1 both legal and
distinct symbols in the proposed syntax? Won't you have the
exact same issue that you do with mis-typing strings?


I think the idea is that if the symbol hasn't been instantiated locally
in an assignment operation, then it will not exist, and "if foo ==
$symbolName" will either raise a NameError or flag some error during
compilation. It cannot do this with string comparisons.

I expect this would require a 2-pass compilation process, the first
pass spotting all references to symbols and instantiating them
appropriately, the second pass resolving these references and noting
any that did not match up.

--
Ben Sizer

Nov 22 '05 #42

P: n/a
Pierre Barbier de Reuille wrote:
Rocco Moretti a écrit :
[...]

I did, but I still don't see why it is an argument against using
strings. The point you may not appreciate is that (C)Python already uses
strings to represent names, as an important part of its introspective
abilities.
Well, I'm well aware of that, but I'm also well aware that's (as you
said yourself) specific to C-Python, so can just *cannot* rely on
strings being used as symbols in the language.


It's true that a different implementation of Python may use a different
internal storage system for names, but as long as the semantics are the
same as CPython, it really doesn't doesn't matter what the internal
storage is. That is to say, as long as the other implementation of
Python has __getattr__ and __dict__, you can use strings to represent
names, regardless of how the interpreter stores them internally.
The point is, why don't provide the programmer to express just what he
needs (that is, some symbolic value like "opened", "blocked", ...) and
let the interpreter use whatever he think is more efficient for him ?
It's just that, for the current interpreters and usage of "symbol-like"
construct, the efficiency gained by the interpreter choosing how to
represent symbols is probably *far* outweighed by the inefficiency and
hassle of implementing and maintaining the symbol syntax in the existing
interpreters.

Besides, "have the programmer specify intent, and allow the interpreter
to substitute a more efficient implementation on the off chance that
interpreter can or wants to" doesn't have much cache in the Python
community.(1) The interpreter could get more efficiency if it knew a
list was fixed length, or contained only ints, or knew that a for loop
was looping over consecutive integers, instead of a random list. But
despite the possibility that there might exist, at some time in the
future, a Python interpreter which *might* optimize such things, we
haven't thrown in variable declarations or integer loop syntaxes yet.

As I've mentioned before, the key to getting feature put into the
language is compelling use cases. Find a (non-hypothetical) Python
program or library which would be improved by addition of <insert your
chosen feature here>, and where the existing alternatives are
inadequate. Lacking that, any attempt to get a feature into the language
is an uphill battle.
But why say a name is a
*string* when it is just an implementation detail ??? Isn't Python
mainly about allowing the programmer to concentrate on important stuff ?


One could flip it around and say that names *not* being strings are an
implementation detail - after all, what is a name in your source code,
besides just a string of ASCII characters? Having just names and strings
simplifies things as well - you have only two items to convert between,
as opposed to three items (names, symbols and strings).

-

(1) The future of Python seems to be towards the PyPy way, where the
interpreter will analyze your code, and automagically determine the most
efficient implementation for your particular use case.
Nov 22 '05 #43

P: n/a
Pierre Barbier de Reuille wrote:
Rocco Moretti a écrit :
[...]

I did, but I still don't see why it is an argument against using
strings. The point you may not appreciate is that (C)Python already uses
strings to represent names, as an important part of its introspective
abilities.
Well, I'm well aware of that, but I'm also well aware that's (as you
said yourself) specific to C-Python, so can just *cannot* rely on
strings being used as symbols in the language.


It's true that a different implementation of Python may use a different
internal storage system for names, but as long as the semantics are the
same as CPython, it really doesn't doesn't matter what the internal
storage is. That is to say, as long as the other implementation of
Python has __getattr__ and __dict__, you can use strings to represent
names, regardless of how the interpreter stores them internally.
The point is, why don't provide the programmer to express just what he
needs (that is, some symbolic value like "opened", "blocked", ...) and
let the interpreter use whatever he think is more efficient for him ?
It's just that, for the current interpreters and usage of "symbol-like"
construct, the efficiency gained by the interpreter choosing how to
represent symbols is probably *far* outweighed by the inefficiency and
hassle of implementing and maintaining the symbol syntax in the existing
interpreters.

Besides, "have the programmer specify intent, and allow the interpreter
to substitute a more efficient implementation on the off chance that
interpreter can or wants to" doesn't have much cache in the Python
community.(1) The interpreter could get more efficiency if it knew a
list was fixed length, or contained only ints, or knew that a for loop
was looping over consecutive integers, instead of a random list. But
despite the possibility that there might exist, at some time in the
future, a Python interpreter which *might* optimize such things, we
haven't thrown in variable declarations or integer loop syntaxes yet.

As I've mentioned before, the key to getting feature put into the
language is compelling use cases. Find a (non-hypothetical) Python
program or library which would be improved by addition of <insert your
chosen feature here>, and where the existing alternatives are
inadequate. Lacking that, any attempt to get a feature into the language
is an uphill battle.
But why say a name is a
*string* when it is just an implementation detail ??? Isn't Python
mainly about allowing the programmer to concentrate on important stuff ?


One could flip it around and say that names *not* being strings are an
implementation detail - after all, what is a name in your source code,
besides just a string of ASCII characters? Having just names and strings
simplifies things as well - you have only two items to convert between,
as opposed to three items (names, symbols and strings).

-

(1) The future of Python seems to be towards the PyPy way, where the
interpreter will analyze your code, and automagically determine the most
efficient implementation for your particular use case.
Nov 22 '05 #44

P: n/a
Pierre Barbier de Reuille wrote:
Proposal
========

First, I think it would be best to have a syntax to represent symbols.
Adding some special char before the name is probably a good way to
achieve that : $open, $close, ... are $ymbols.


How about using the prefix "symbol." instead of "$"?
symbol.x symbol.x symbol.y symbol.y x = symbol.x
x == symbol.x True x == symbol.y False symbol.file.opened symbol.file.opened symbol.file.closed symbol.file.closed symbol.spam(symbol.eggs) symbol.spam(symbol.eggs)

And the definition of symbol that I used:
class symbol(object):

.... class __metaclass__(type):
.... def __getattr__(cls, name):
.... return symbol(name)
.... def __getattr__(self, name):
.... return symbol('%s.%s' % (self.name, name))
.... def __init__(self, name):
.... self.name = name
.... def __eq__(self, other):
.... return self.name == other.name
.... def __repr__(self):
.... return '%s.%s' % (type(self).__name__, self.name)
.... def __call__(self, *args):
.... arg_str = ', '.join(str(arg) for arg in args)
.... return symbol('%s(%s)' % (self.name, arg_str))
....

It doesn't work with "is", but otherwise I think it's pretty close to
your proposal, syntax-wise. Is there something obvious this won't
address for you?

STeVe
Nov 22 '05 #45

P: n/a
Pierre Barbier de Reuille wrote:
Proposal
========

First, I think it would be best to have a syntax to represent symbols.
Adding some special char before the name is probably a good way to
achieve that : $open, $close, ... are $ymbols.


How about using the prefix "symbol." instead of "$"?
symbol.x symbol.x symbol.y symbol.y x = symbol.x
x == symbol.x True x == symbol.y False symbol.file.opened symbol.file.opened symbol.file.closed symbol.file.closed symbol.spam(symbol.eggs) symbol.spam(symbol.eggs)

And the definition of symbol that I used:
class symbol(object):

.... class __metaclass__(type):
.... def __getattr__(cls, name):
.... return symbol(name)
.... def __getattr__(self, name):
.... return symbol('%s.%s' % (self.name, name))
.... def __init__(self, name):
.... self.name = name
.... def __eq__(self, other):
.... return self.name == other.name
.... def __repr__(self):
.... return '%s.%s' % (type(self).__name__, self.name)
.... def __call__(self, *args):
.... arg_str = ', '.join(str(arg) for arg in args)
.... return symbol('%s(%s)' % (self.name, arg_str))
....

It doesn't work with "is", but otherwise I think it's pretty close to
your proposal, syntax-wise. Is there something obvious this won't
address for you?

STeVe
Nov 22 '05 #46

P: n/a

Steven Bethard wrote:
Pierre Barbier de Reuille wrote:
Proposal
========

First, I think it would be best to have a syntax to represent symbols.
Adding some special char before the name is probably a good way to
achieve that : $open, $close, ... are $ymbols.


How about using the prefix "symbol." instead of "$"?
>>> symbol.x


I recognize 3 symbols: a "symbol" a dot and another symbol. So I
wouldn't call this a symbol. Maybe a "diabolon"? Other languages have
symbols, Python has diaboli ;)

Kay

Nov 22 '05 #47

P: n/a

Steven Bethard wrote:
Pierre Barbier de Reuille wrote:
Proposal
========

First, I think it would be best to have a syntax to represent symbols.
Adding some special char before the name is probably a good way to
achieve that : $open, $close, ... are $ymbols.


How about using the prefix "symbol." instead of "$"?
>>> symbol.x


I recognize 3 symbols: a "symbol" a dot and another symbol. So I
wouldn't call this a symbol. Maybe a "diabolon"? Other languages have
symbols, Python has diaboli ;)

Kay

Nov 22 '05 #48

This discussion thread is closed

Replies have been disabled for this discussion.