Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Python > Re: Modifying the {} and [] tokens

Reply
Thread Tools

Re: Modifying the {} and [] tokens

 
 
Andrew Dalke
Guest
Posts: n/a
 
      08-23-2003
Geoff Howland:
> I want to modify the {} and [] tokens to contain additional
> functionality they do not currently contain, such as being able to add
> dicts to dicts, and other things that would be very helpful for me and
> my team mates to have.


You can't. Not without changing the underlying implementation.

> So I can obviously override dict and it works when I specifically call
> dict(), but it does not work with the syntax sugar {}.


That's because you created a new dict. You didn't modify the
actual type {} uses in the intepreter. {} is not simple syntactic sugar
for dict() in the local namespace. BTW, if it were, then

dict = 8
a = {3: 4}

would fail.

> How can I make this work? Can this also work to overload strings with
> the "" and '' tokens?


You can't. What's wrong with using your derived dict? Why must you
use {}?

You can't modify the fundamental type used by strings either.

Andrew
http://www.velocityreviews.com/forums/(E-Mail Removed)


 
Reply With Quote
 
 
 
 
Geoff Howland
Guest
Posts: n/a
 
      08-23-2003
On Sat, 23 Aug 2003 04:41:20 GMT, "Andrew Dalke"
<(E-Mail Removed)> wrote:

>Geoff Howland:
>> I want to modify the {} and [] tokens to contain additional
>> functionality they do not currently contain, such as being able to add
>> dicts to dicts, and other things that would be very helpful for me and
>> my team mates to have.

>
>You can't. Not without changing the underlying implementation.


The implementation in the C code, or implementation at the Python
level?

As long as this stays in Python, like as a module that can be included
or not, then I think it would be helpful. I think a lot of the things
I would like to do might actually be good in the language, but maybe
they've already been thrown out, or something. For now, I dont have
an entire list and implementation of everything I would like to see to
really present as a "possible change list", so I'd just like to be
able to do this to assist in my own teams work.

There is history and other info beyond this besides "I think it would
be neat", but that is team private business so I dont want to drag it
out here. This would just be helpful.

>> So I can obviously override dict and it works when I specifically call
>> dict(), but it does not work with the syntax sugar {}.

>
>That's because you created a new dict. You didn't modify the
>actual type {} uses in the intepreter. {} is not simple syntactic sugar
>for dict() in the local namespace. BTW, if it were, then
>
> dict = 8
> a = {3: 4}
>
>would fail.


Right, so is there a way to change this? I know the syntax I tried
doesnt work and for obvious type reasons, since you wouldnt want to do
this by accident.

Perhaps something has to be registered in some Python
variable/class/module-list I am not aware of that would make this
happen? I am ok with the consequences of potentially introducing
oddities into my code from the Norm for this flexibility.

>> How can I make this work? Can this also work to overload strings with
>> the "" and '' tokens?

>
>You can't. What's wrong with using your derived dict? Why must you
>use {}?


The reason for using it is that it is easier to code using the default
containers than having to specify things. IMO, there are some things
missing from the language, and while maybe they wont be added, I would
like to have them.

{} + {}, {} - {}. [] - [], etc

These operations would be useful, as well as additional functions that
are commonly performed and have to be put in separate modules.

I would also like to move all the usual operational functions into
some of these, such as instead of len([]), you could do [].len().
More consistent for some of my team to read.

If it's impossible without creating a new EXE, then I wont have a
choice. If it is not impossible, then I would like to be able to add
some things to the standard containers that are already very powerful
but seem to be missing some basics to complete their operational sets.

>You can't modify the fundamental type used by strings either.


I'd have the same questions above for this.


-Geoff Howland
http://ludumdare.com/
 
Reply With Quote
 
 
 
 
OKB (not okblacke)
Guest
Posts: n/a
 
      08-23-2003
Geoff Howland wrote:

> IMO, there are some things
> missing from the language, and while maybe they wont be added, I

would
> like to have them.
>
> {} + {}, {} - {}. [] - [], etc


I'm a little puzzled as to why you'd need these, since it seems
like all they allow you to is hard-code a certain combination of
statically defined objects. That is, if you're going to do

{ 'a': 1, 'b': 2 } + { 'c': 3, 'd': 4}

. . .why not just write

{ 'a': 1, 'b': 2, 'c': 3, 'd': 4}

in the first place?

--
--OKB (not okblacke)
"Do not follow where the path may lead. Go, instead, where there is
no path, and leave a trail."
--author unknown
 
Reply With Quote
 
Geoff Howland
Guest
Posts: n/a
 
      08-23-2003
On 23 Aug 2003 07:02:53 GMT, "OKB (not okblacke)" <(E-Mail Removed)>
wrote:

>> {} + {}, {} - {}. [] - [], etc

>
> I'm a little puzzled as to why you'd need these, since it seems
>like all they allow you to is hard-code a certain combination of
>statically defined objects. That is, if you're going to do
>
>{ 'a': 1, 'b': 2 } + { 'c': 3, 'd': 4}
>
> . . .why not just write
>
>{ 'a': 1, 'b': 2, 'c': 3, 'd': 4}
>
> in the first place?


Because I wouldn't just be using {} on a line, I would create a
dictionary with it and then use it around, and then at some point
later I may want to add another dictionary to it, or find the union or
differences between two dictionaries.

Ruby has this built in, it's useful, it's complete. It's obvious what
is happening, so it's not unclean. It's allowed for other containers.


-Geoff Howland
http://ludumdare.com/
 
Reply With Quote
 
Dave Brueck
Guest
Posts: n/a
 
      08-23-2003
On Saturday 23 August 2003 10:12 am, Geoff Howland wrote:
> On 23 Aug 2003 08:18:49 -0700, (E-Mail Removed) (Michele Simionato)
>
> >Python tries hard not to modify its basic syntax, so you must stay
> >with the above. Pythonista would argue that this is a strenght of the
> >language: "explicit is better than implicit".

>
> I agree with this philosophy too. I'm not sure where the changes I'm
> looking to fail to be explicity.
>
> {} + {} makes sense right? You are adding them together. There will
> obviously be a possibility of key clobbering, but then you could run
> something like {}.intersect() and get the keys that will be clobbered
> (if it existed).


Does {'a':4} + {'a':6} equal
(a) {'a':10}
(b) {'a':[4,6]}
(c) {'a':4}
(d) {'a':6}

???

I can think of reasonable & realistic use cases where each one is the
"obvious" choice.

> len([])
>
> [].len()


If you can conjure up the right Google Groups query, this has been discussed
many times in the past (and by that I mean some good points have been raised
that you might find interesting). In particular, I remember Alex Martelli
making a good argument for len(obj) over obj.len(). For my part, now that I'm
used to len(obj), the form obj.len() seems too much like
OO-just-for-the-sake-of-OO, which isn't very compelling.

-Dave

 
Reply With Quote
 
Geoff Howland
Guest
Posts: n/a
 
      08-23-2003
>>> So I can obviously override dict and it works when I specifically call
>>> dict(), but it does not work with the syntax sugar {}.

>>
>>That's because you created a new dict. You didn't modify the
>>actual type {} uses in the intepreter. {} is not simple syntactic sugar
>>for dict() in the local namespace. BTW, if it were, then
>>
>> dict = 8
>> a = {3: 4}
>>
>>would fail.

>
>Right, so is there a way to change this? I know the syntax I tried
>doesnt work and for obvious type reasons, since you wouldnt want to do
>this by accident.
>
>Perhaps something has to be registered in some Python
>variable/class/module-list I am not aware of that would make this
>happen? I am ok with the consequences of potentially introducing
>oddities into my code from the Norm for this flexibility.


I've explored all of __builtins__ that I have been able to, and
replacing dict there does nothing either, so I'm beginning to think
that {}, [], etc are bound to types in the C code only and not
available at all through Python to be re-typed.

Is this correct? Is there no way to change type on these expression
delimeters?

I would think that somewhere this is a Python accessable definitely of
what <type 'dict'> is that could be altered, so far I cant seem to
find any reference to it through the Python Language Reference, Python
in a Nutshell, or any google search.

Python in a Nutshell specifies that dict(d={}) is essentially d = {},
but I can't find a description of how this token/expression to type
binding happens.

It seems like it would be really handy to add features to all
containers equally though, especially since you should be able to get
new functionality from any code written even if it didn't know about
your new features because it could instantiate with the new type.

BTW, some of the other comments in my team have been for a desire of
more inclusive OO, such as [].len() instead of len([]), and this sort
of thing. Having them builtin is obviously great and useful, but it
feels wrong to some people and I'm trying to work on making things
smoother instead of just forcing them to adapt (which they may not
choose to do).


-Geoff Howland
http://ludumdare.com/
 
Reply With Quote
 
Christos TZOTZIOY Georgiou
Guest
Posts: n/a
 
      08-23-2003
On Sat, 23 Aug 2003 09:16:13 GMT, rumours say that Geoff Howland
<(E-Mail Removed)> might have written:

[snip of python's by design inability to modify the base C types: dict,
str, list etc]

>Ruby has this built in, it's useful, it's complete. It's obvious what
>is happening, so it's not unclean. It's allowed for other containers.


It seems that code "terseness" is more important to you than code
readability. I can sympathise with that, perhaps I'd like that too, but
I believe I fully understand Guido's decisions over the years to
disallow that kind of stuff.

I really don't mind subclassing base types and using MyDict() instead of
{}. I want to be able to make my own APIs (MyDict.update *could* blow
whistles and roll twice on the floor before resetting the machine), but
I also want a steady and well-known API for base types (dict.update
*should* update a dictionary from another one).

You can always roll off a customised Python interpreter, of course, but
it won't be Python anymore.

With all due respect, Geoff, if this stuff is really important to you,
use Ruby.
--
TZOTZIOY, I speak England very best,
Microsoft Security Alert: the Matrix began as open source.
 
Reply With Quote
 
Robert Kern
Guest
Posts: n/a
 
      08-23-2003
In article <(E-Mail Removed)>,
Geoff Howland <(E-Mail Removed)> writes:

[snip]

> I've explored all of __builtins__ that I have been able to, and
> replacing dict there does nothing either, so I'm beginning to think
> that {}, [], etc are bound to types in the C code only and not
> available at all through Python to be re-typed.
>
> Is this correct? Is there no way to change type on these expression
> delimeters?
>
> I would think that somewhere this is a Python accessable definitely of
> what <type 'dict'> is that could be altered, so far I cant seem to
> find any reference to it through the Python Language Reference, Python
> in a Nutshell, or any google search.
>
> Python in a Nutshell specifies that dict(d={}) is essentially d = {},
> but I can't find a description of how this token/expression to type
> binding happens.


The parser compiles {} into the BUILD_MAP opcode which the eval loop
interprets by calling PyDict_New(). This creates a dict object
independently of whatever __builtins__.dict is bound to.

I discovered this by disassembling some code and looking up the opcode
in the bytecode interpreter eval loop (Python/ceval.c).

>>> import dis
>>> code = compile("{}", "<test>", "single")
>>> dis.dis(code)

1 0 BUILD_MAP 0
3 PRINT_EXPR
4 LOAD_CONST 0 (None)
7 RETURN_VALUE

Reading the Language Reference can help a lot, too.

> It seems like it would be really handy to add features to all
> containers equally though, especially since you should be able to get
> new functionality from any code written even if it didn't know about
> your new features because it could instantiate with the new type.


I think that's precisely the reason why this feature will probably
never make it into Python. I, for one, don't want a module that I import
to change the meaning of a literal just because that module wants to use
a funky form of dict internally.

It's possible it could be encapsulated on a per-file basis, but that
would probably require adding another opcode for each builtin type.

In the end, it's just not worth the trouble. 99.9% of the time, I think
you will find that subclassing the builtin types and giving the new
classes short names will suffice. I mean, how much of a hardship is it
to do the following:

class d(dict):
def __add__(self, other):
# stuff

d({1:2}) + d({3:4})

It's only 3 extra characters each time; everyone who reads it knows what
is going on, knows to look for "class d" to find out how it's different
from a normal dict; it doesn't screw up other people's code; and it even
allows for you to define "class YetAnotherDict(dict)" which has
completely different behavior and use both at the same time.

If you're still not convinced, ask yourself these questions:

* How would you apply the new subclass?
- Only on new literals after the subclass definition (and registry of
the subclass with some special hook)?
- On every new object that would normally have been the base type?
- On every previously existing object with the base type?
- In just the one module? or others which import it? or also in
modules imported after the one with the subclass?

* How does your choice above work with code compiled on-the-fly with
eval, exec or execfile?

* How do you deal with multiple subclasses being defined and registered?

* How would you pass in initialization information?
E.g. say I want to limit the length of lists

class LimitList(list):
def __init__(self, maxlength, data=[]):
self.maxlength = maxlength
list.__init__(self, data)
def append(self, value):
if len(self) == self.maxlength:
raise ValueError, "list at maximum length"
else:
list.append(self, value)

* Can I get a real dict again if wanted to?

* Given your choices above, how can you implement it in such a way that
you don't interfere with other people's code by accident?

Okay, so the last one isn't really fair, but the answers you give on the
other questions should help define in your mind the kind of behavior you
want. Reading up on Python internals with the Language Reference, the
dis module documentation, and some source code should give you an idea
of how one might go about an implementation and (more importantly) the
compromises one would have to make.

Then compare these specific features with the current way. Which is
safer? Which is more readable by someone unfamiliar with the code? Which
is more flexible? Which saves the most typing?

> BTW, some of the other comments in my team have been for a desire of
> more inclusive OO, such as [].len() instead of len([]), and this sort
> of thing. Having them builtin is obviously great and useful, but it
> feels wrong to some people and I'm trying to work on making things
> smoother instead of just forcing them to adapt (which they may not
> choose to do).


My condolences on having to deal with such a team. It seems a little
silly to me to equate OO with Everything-Must-Be-a-Method-Call. But if
they insist, point them at [].__len__(). len([]) just calls [].__len__()
anyways. After writing code like that for a while, they'll probably get
over their method fixation.

> -Geoff Howland
> http://ludumdare.com/


--
Robert Kern
(E-Mail Removed)

"In the fields of hell where the grass grows high
Are the graves of dreams allowed to die."
-- Richard Harter
 
Reply With Quote
 
Michele Simionato
Guest
Posts: n/a
 
      08-23-2003
Geoff Howland <(E-Mail Removed)> wrote in message news:<(E-Mail Removed)>. ..
> On 23 Aug 2003 07:02:53 GMT, "OKB (not okblacke)" <(E-Mail Removed)>
> wrote:
>
> >> {} + {}, {} - {}. [] - [], etc

> >
> > I'm a little puzzled as to why you'd need these, since it seems
> >like all they allow you to is hard-code a certain combination of
> >statically defined objects. That is, if you're going to do
> >
> >{ 'a': 1, 'b': 2 } + { 'c': 3, 'd': 4}
> >
> > . . .why not just write
> >
> >{ 'a': 1, 'b': 2, 'c': 3, 'd': 4}
> >
> > in the first place?

>
> Because I wouldn't just be using {} on a line, I would create a
> dictionary with it and then use it around, and then at some point
> later I may want to add another dictionary to it, or find the union or
> differences between two dictionaries.
>
> Ruby has this built in, it's useful, it's complete. It's obvious what
> is happening, so it's not unclean. It's allowed for other containers.
>
>
> -Geoff Howland
> http://ludumdare.com/


Subclass dict, define __add__ and __sub__ and it will work, but NOT
with the brace syntax. You must use something like

mydict(a=1,b=2)+mydict(c=3,d=4)

Python tries hard not to modify its basic syntax, so you must stay
with the above. Pythonista would argue that this is a strenght of the
language: "explicit is better than implicit".

Michele Simionato, Ph. D.
(E-Mail Removed)
http://www.phyast.pitt.edu/~micheles
--- Currently looking for a job ---
 
Reply With Quote
 
Geoff Howland
Guest
Posts: n/a
 
      08-23-2003
On Sat, 23 Aug 2003 16:40:17 +0300, Christos "TZOTZIOY" Georgiou
<(E-Mail Removed)> wrote:

>On Sat, 23 Aug 2003 09:16:13 GMT, rumours say that Geoff Howland
><(E-Mail Removed)> might have written:
>
>[snip of python's by design inability to modify the base C types: dict,
>str, list etc]


This post begins to read as an insult here, and continues. My
incredible gall at thinking something may be better if it was changed
and wanting to try it! I should be pelted with rocks for speaking the
name Jehova.

Is this really the way this group is going to continue?

>>Ruby has this built in, it's useful, it's complete. It's obvious what
>>is happening, so it's not unclean. It's allowed for other containers.

>
>It seems that code "terseness" is more important to you than code
>readability. I can sympathise with that, perhaps I'd like that too, but
>I believe I fully understand Guido's decisions over the years to
>disallow that kind of stuff.


[] + [] is allowed. Right?

{} + {} is not allowed.

len([]) is allowed.

[].len() is not allowed.

Why? I respect Guidos decsions, Python needs a strong leader to make
them and it got where it is (great language) by having him and the
rest of the community help out in this regard.

Is now no one allowed to say "hey, I think this should be done, and
I'd like to make it happen to give it a try"? It's not like if it
becomes a problem it couldn't be reverted and lesson learned right?
Programming is ABOUT experimentation, not dogmatic obedience.

>I really don't mind subclassing base types and using MyDict() instead of
>{}. I want to be able to make my own APIs (MyDict.update *could* blow
>whistles and roll twice on the floor before resetting the machine), but
>I also want a steady and well-known API for base types (dict.update
>*should* update a dictionary from another one).


Why should it matter what you mind? It's my code.

>You can always roll off a customised Python interpreter, of course, but
>it won't be Python anymore.
>
>With all due respect, Geoff, if this stuff is really important to you,
>use Ruby.


Yes, throw the heathen into another language. I'm not good enough for
this one.

I find this attitude really insulting. I like Python for what it is,
that doesnt mean I dont think there are some things that could be
better and want to try them. I wanted to know if it's possible, so I
asked. I think it's important, so I persisted. Get over it. Stop
making this place an unpleasant place to ask questions in fear of not
asking in a Pythonic enough way.

Not the first time I've seen this here, I'm sure it wont be the last.
Not sure how many people never picked it up because they were smacked
down before they found their groove in Python.

I'm sorry this sounds heavy and upset, but I would like this place to
not feel so bitter against exploratory questions. Bounds are set in
Python, it's good. It doesn't mean people shouldn't ask and explore
and find out for themselves what is best if it is possible. I could
even go and change all the Python C source to make this work, who is
it going to hurt but myself? It may even bring me valuable insight
that I can then share as an _opinion_ with others who ask later (note,
not telling them to use another language because they want to do
something I dont agree with).


-Geoff Howland
http://ludumdare.com/
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Byte Offsets of Tokens, Ngrams and Sentences? Muhammad Adeel Python 2 08-06-2010 10:06 AM
Finding and replacing Invalid Tokens in an XML document Ben Holness Perl 0 01-06-2006 12:11 PM
string into tokens =?Utf-8?B?TFc=?= ASP .Net 1 10-13-2005 06:53 PM
RE: string into tokens =?Utf-8?B?RWx0b24gVw==?= ASP .Net 0 10-13-2005 06:06 PM
Struts Tokens - Newbie Dale Java 1 02-10-2004 11:48 PM



Advertisments