FAQ
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.

(Please dont kick off a bunch of responses about how this may be a
problem for people supporting code, or copying it out and it doesnt
work. :) )

I have currently tried this:
class dict(dict):
... def add(self, name, value):
... self.__setitem__(name, value)
a = dict()
a.add('five', 'six')
a
{'five': 'six'}
b = {}
dict.add('blah', 5)
Traceback (most recent call last):
File "<input>", line 1, in ?
AttributeError: 'dict' object has no attribute 'add'

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

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


-Geoff Howland
http://ludumdare.com/

Search Discussions

  • Andrew Dalke at Aug 23, 2003 at 4:41 am

    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
    dalke at dalkscientific.com
  • Geoff Howland at Aug 23, 2003 at 5:48 am

    On Sat, 23 Aug 2003 04:41:20 GMT, "Andrew Dalke" 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/
  • OKB (not okblacke) at Aug 23, 2003 at 7:02 am

    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
  • Geoff Howland at Aug 23, 2003 at 9:16 am

    On 23 Aug 2003 07:02:53 GMT, "OKB (not okblacke)" 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/
  • Christos TZOTZIOY Georgiou at Aug 23, 2003 at 1:40 pm
    On Sat, 23 Aug 2003 09:16:13 GMT, rumours say that Geoff Howland
    <ghowland at lupineNO.SPAMgames.com> 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.
  • Geoff Howland at Aug 23, 2003 at 4:04 pm

    On Sat, 23 Aug 2003 16:40:17 +0300, Christos "TZOTZIOY" Georgiou wrote:

    On Sat, 23 Aug 2003 09:16:13 GMT, rumours say that Geoff Howland
    <ghowland at lupineNO.SPAMgames.com> 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/
  • Roy Smith at Aug 23, 2003 at 4:40 pm

    Geoff Howland wrote:
    {} + {} is not allowed.
    What would it mean? What would you do if you had two dicts:

    d1 = {'a':1, 'b':2}
    d2 = {'a':42}

    what would the value of (d1+d2)['a'] be?
  • Geoff Howland at Aug 23, 2003 at 5:10 pm

    On Sat, 23 Aug 2003 12:40:05 -0400, Roy Smith wrote:
    Geoff Howland wrote:
    {} + {} is not allowed.
    What would it mean? What would you do if you had two dicts:

    d1 = {'a':1, 'b':2}
    d2 = {'a':42}

    what would the value of (d1+d2)['a'] be?
    I dont think it matters. Pick one and make that the standard.

    The current norm is "last one in clobbers the existing", so keep that
    and d = d1 + d2 ; d['a'] == 42

    I really dont think it matters that its not perfect, what matters is
    that it's possible and if you have unique keys, or dont care about
    clobbering, then you dont have to do this yourself.

    If you do care, you have to write your own routine. As it stands now,
    everyone has to do this every time, even if they would never encounter
    the clobbering situation, or dont care.

    It's the same reason an exception isnt thrown for this:

    {'a':5, 'a':6}

    Obviously, you cant have both, but it's legal. As long as the rules
    are defined and it stays consistent every time, then it can be of use.

    Same for subtraction to remove overlaps, etc. It's an operator, so it
    only has one use per term. Even if it's not handling all cases, why
    make everyone re-implement the same one 80% of the time?

    In my work, this would be useful functionality, and maybe other places
    it would be dangerous and thus it shouldnt be added to the language
    because it's better not to mess with it. That's fine, then I was
    still looking for a way to make it work just with _my_ code. Since it
    is now clear to me that this isn't possible with the {} tokens, then I
    will just go about it the way that does work. :)

    I just wanted the best solution for my own problem at hand.


    -Geoff Howland
    http://ludumdare.com/
  • Roy Smith at Aug 23, 2003 at 5:16 pm

    Geoff Howland wrote:
    As it stands now, everyone has to do this every time,
    I suppose that's true. On the other hand, I can't remember the last
    time I ever wanted to add two dictionaries.
  • Geoff Howland at Aug 23, 2003 at 5:19 pm

    On Sat, 23 Aug 2003 13:16:47 -0400, Roy Smith wrote:
    Geoff Howland wrote:
    As it stands now, everyone has to do this every time,
    I suppose that's true. On the other hand, I can't remember the last
    time I ever wanted to add two dictionaries.
    Then you wouldn't be effected one way or the other. :)


    -Geoff Howland
    http://ludumdare.com/
  • Roy Smith at Aug 23, 2003 at 5:29 pm

    Geoff Howland wrote:
    Then you wouldn't be effected one way or the other. :)
    Sure I will. It will be one more thing I potentially need to know to
    understand somebody else's code.
  • Geoff Howland at Aug 23, 2003 at 6:01 pm

    On Sat, 23 Aug 2003 13:29:10 -0400, Roy Smith wrote:
    Geoff Howland wrote:
    Then you wouldn't be effected one way or the other. :)
    Sure I will. It will be one more thing I potentially need to know to
    understand somebody else's code.
    True. Though, again, as long as it works the same way all the time,
    then it shouldn't be a problem.


    -Geoff Howland
    http://ludumdare.com/
  • Hans Nowak at Aug 23, 2003 at 6:51 pm

    Geoff Howland wrote:
    On Sat, 23 Aug 2003 12:40:05 -0400, Roy Smith wrote:

    Geoff Howland wrote:
    {} + {} is not allowed.
    What would it mean? What would you do if you had two dicts:

    d1 = {'a':1, 'b':2}
    d2 = {'a':42}

    what would the value of (d1+d2)['a'] be?

    I dont think it matters. Pick one and make that the standard.
    Ah, but I think it matters to Guido, or dict operators like these would have
    been added long ago.

    The problem here is that, when looking at d1 + d2, it is not obvious what is
    going on. If the same key appears in both d1 and d2, what will the resulting
    dict have? The value in d1? The value in d2? Or maybe an exception will be
    raised? Different people will have different notions here about what is
    "obvious" and "natural".

    "Pick one and make that the standard" may work in some other languages, but
    that is usually not how Python's design works. If there is not "one obvious
    way", chances are it won't make it into the language. (Of course, there are
    exceptions... but this seems to be a rule-of-thumb.)

    Fortunately, you can always roll your own dict with the behavior *you* find
    natural and obvious. So you can add a + operator to your custom dict, etc.
    However, it is not possible to change the behavior of literals. They will
    always behave (and be instances of) like the original, built-in object. As a
    result, you'll be forced to write something like

    d1 = mydict({'a': 1, 'b': 2})
    d2 = mydict({'a': 42})
    d3 = d1 + d2

    On a side note, I don't think the other poster was trying to be facetious when
    he suggested you use Ruby... if this language feature is really important to
    you, then maybe Ruby may be a better choice, since that language is more
    "malleable" than Python.

    HTH,

    --
    Hans (hans at zephyrfalcon.org)
    http://zephyrfalcon.org/
  • Christos TZOTZIOY Georgiou at Aug 23, 2003 at 6:56 pm
    On Sat, 23 Aug 2003 16:04:52 GMT, rumours say that Geoff Howland
    <ghowland at lupineNO.SPAMgames.com> might have written:
    On Sat, 23 Aug 2003 16:40:17 +0300, Christos "TZOTZIOY" Georgiou
    wrote:
    On Sat, 23 Aug 2003 09:16:13 GMT, rumours say that Geoff Howland
    <ghowland at lupineNO.SPAMgames.com> 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.
    I am sorry, Geoff, but I can't understand how you perceived my post as
    insulting. If I did understand a way, I would apologise. I just
    snipped stuff in order to make my post shorter, according to netiquette.
    How can the phrase inside the brackets seem insulting to you? Geoff,
    please justify your clause, and I will gladly apologise.
    Is this really the way this group is going to continue?
    I don't know, I can speak for myself only. How many people have
    responded to you this "way" to make you wonder about the whole group?
    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.
    This is the deal, indeed; for example, I would enjoy very much generator
    comprehensions in the language, and yet they were rejected.
    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.
    My reply came to your specific feature request, ie Python allowing you
    to modify the base types; your asking if *any* feature request is
    disallowed is not justified. I consider your question similar to the
    following dialog:

    - Can I have cherry pie with my meal?
    - No, because the cook has decided it does not match with your meal,
    which is fish.
    - So no one is allowed to ask for dessert here?

    I believe that the symbolism is childish, and this indeed you might find
    it insulting, although it isn't. I am not as fluent in English as I
    would like, so this is my way to express the general feeling I got from
    your reply; I call it "black-and-white", or "ping-pong", lacking a
    better English word, and describes a two-way communication where a
    disagreement on the one side is perceived magnified as total rejection
    on the other side.
    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.
    What should it matter what you mind then? It's Guido's language.
    Either we both are allowed to say our minds, or not. My opinion is as
    important as yours. Keep that in mind, please.

    The fact is, the subject has been brought up in the past, and it has
    been skipped. I am not sure if has been rejected, so you might have a
    chance. If you are as warm about this subject as you seem to be, write
    a PEP; my vote will probably be positive. But Guido is the one to
    convince, and he listens; my experience so far has shown that he never
    replies the way you do, and that is good.

    This URL should be useful:
    http://www.python.org/peps/pep-0001.html
    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.
    Your last statement is unjustified too, and "black-and-white", assuming
    hidden meanings in my words. Geoff, I am picking my words very
    carefully because I don't want to make you jump to the ceiling with
    rage. Please read, don't assume.

    My sentence was a practical (and respectful!) suggestion; Ruby already
    has what you want, and you like it, so why not use it, since the Python
    community (and Guido most of all) are against such a modification? Did
    you do a research in older newsgroup threads before posting?
    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.
    Perhaps you are irritated by earlier discussions, whom I'm not in the
    mood to look for; this might explain your misinterpretation of my
    message. Geoff, my attitude was not insulting. It was practical.
    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, please. Your last statement inside the parentheses is based on
    false assumptions, which is bad, because you already had the data. From
    my previous post I said I'd possibly like what you suggest, and I meant
    it --and still do. If you don't believe me, if you feel that I am
    bullying you, lying to you, using sarcasm or irony on you, then I'll
    have to give up.

    Don't spend your energy fighting with me (one-side fights: only on
    USENET :), write a PEP and find good arguments for it.
    --
    TZOTZIOY, I speak England very best,
    Microsoft Security Alert: the Matrix began as open source.
  • Geoff Howland at Aug 23, 2003 at 7:22 pm

    On Sat, 23 Aug 2003 21:56:08 +0300, Christos "TZOTZIOY" Georgiou wrote:
    [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.
    I am sorry, Geoff, but I can't understand how you perceived my post as
    insulting. If I did understand a way, I would apologise. I just
    snipped stuff in order to make my post shorter, according to netiquette.
    How can the phrase inside the brackets seem insulting to you? Geoff,
    please justify your clause, and I will gladly apologise.
    If you didn't mean it as insulting, than I am very sorry for taking it
    so and responding in the way I did.

    I saw it as I was being told that I am ignoring the good design
    philosophies of Python, and as such I should move on to another
    language. I have been told exactly this thing before (without being
    mistaking) so I suppose I am more sensitive to it than I would have
    been had I not had it said before.

    Sorry for misunderstanding you and becoming upset about it. :)
    Is this really the way this group is going to continue?
    I don't know, I can speak for myself only. How many people have
    responded to you this "way" to make you wonder about the whole group?
    Maybe 2 here, to more or lesser degrees. Probably about 5 times on
    python IRC channels.
    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.
    This is the deal, indeed; for example, I would enjoy very much generator
    comprehensions in the language, and yet they were rejected.
    Exactly, and as long as it's ok to bring them up, then all is well. I
    was just feeling like I was being rebuked for doing so. In
    retrospect, I probably should have just not responded at all to the
    thread portion that I felt that way about, as other people were giving
    me answers I thought were completely even.

    I do appreciate Python's design decisions. It's what keeps it from
    becomming the things I dont like about Perl, where that does not seem
    to be the case. However, I still like having the rope to shoot myself
    in the foot if I so desire, but if it doesnt exist I'll get by without
    it. :)
    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.
    My reply came to your specific feature request, ie Python allowing you
    to modify the base types; your asking if *any* feature request is
    disallowed is not justified. I consider your question similar to the
    following dialog:

    - Can I have cherry pie with my meal?
    - No, because the cook has decided it does not match with your meal,
    which is fish.
    - So no one is allowed to ask for dessert here?
    Well, this was because I took your post as hostility. I'm not sure I
    was out there in interpretting this way, as usually telling someone to
    "go somewhere else" when they inquire about things is meant that way.
    I believe that the symbolism is childish, and this indeed you might find
    it insulting, although it isn't. I am not as fluent in English as I
    would like, so this is my way to express the general feeling I got from
    your reply; I call it "black-and-white", or "ping-pong", lacking a
    better English word, and describes a two-way communication where a
    disagreement on the one side is perceived magnified as total rejection
    on the other side.
    Im fine with the things being one way or another, no problems at all
    with it. I understand why base types arent allowed to be modified,
    cause while you could do it without damaing things, it would be a lot
    more likely that things would be damaged over time and you might never
    know you're including a module that changes behavior. It makes sense.

    That doesn't mean it wouldnt be useful, which is why I was inquiring.
    If it was possible, I'd probably do it because of it's usefulness. If
    it became a problem later, I could correct that. I am flexible that
    way, it is probably a good thing Guido and the Python community that
    helps design Python is not. Checks and balances.

    As long as it's still ok to inquire.

    I think the last thing that was really brought up in this "how dare
    you" type style was someone inquiring about protecting their code from
    people reading it. Some people near-flamed the guy for asking how to
    do this, and I think it is ridiculous. Everyone has their own
    purposes for tools, so my ire was up. :)
    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.
    What should it matter what you mind then? It's Guido's language.
    Either we both are allowed to say our minds, or not. My opinion is as
    important as yours. Keep that in mind, please.
    Sure, but you were answering a question and saying "no" based on your
    opinions. That's tangential to the question, which is that I want to
    do something. That it's not possible is topical. That
    Guido/PythonLabs doesnt approve is topical, in the sense of a style
    guide. That you don't approve is topical on an advice level, but not
    on a "how do I do this" level.

    Thats my view of it, and since I was thinking you were saying I should
    "move on to another language for not liking everything exactly as it
    is now", then I took it as a judgement placement, rather than advise.

    Again, my misunderstanding and my appology.
    The fact is, the subject has been brought up in the past, and it has
    been skipped. I am not sure if has been rejected, so you might have a
    chance. If you are as warm about this subject as you seem to be, write
    a PEP; my vote will probably be positive. But Guido is the one to
    convince, and he listens; my experience so far has shown that he never
    replies the way you do, and that is good.

    This URL should be useful:
    http://www.python.org/peps/pep-0001.html
    I actually wanted to do a proof of concept and try it before writing a
    PEP. Cause if it turns out to suck in practice, why bother with the
    PEP? I think now I would have to change the Python C code in order to
    try it, and that isnt acceptable to me as I wouldnt be able to really
    put it into effect in the real world and see if it works.

    I'm all for putting in the time to write and push a PEP if I think
    something is really worth it and I have proof in my own eyes. I'm
    also accepting if it gets rejected because it doesn't fit with the
    language. So far I haven't gotten to a point where I am confident
    enough about something I think should work a different way to do this.
    Maybe someday it will happen, maybe it wont. I'd like to help, but
    dont want to make suggestions that aren't really helpful until I'm
    convinced myself that they are.
    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.
    Your last statement is unjustified too, and "black-and-white", assuming
    hidden meanings in my words. Geoff, I am picking my words very
    carefully because I don't want to make you jump to the ceiling with
    rage. Please read, don't assume.
    The difficulties of reading text. I showed this message to 2 other
    people, and they also thought it was telling me off instead of just
    explaining something to me. However, I still appologize for
    misreading your intentions and my response.
    My sentence was a practical (and respectful!) suggestion; Ruby already
    has what you want, and you like it, so why not use it, since the Python
    community (and Guido most of all) are against such a modification? Did
    you do a research in older newsgroup threads before posting?
    Yeah, I searched around for about 6 hours before posting this, also
    poking around in different books and the python interpretter. I
    didn't find this topic covered, but sometimes it's very hard to find
    things with common words like: python, dict, modification/override,
    etc.

    Ruby is a great language, but there are a couple reasons it wont be
    used in this circumstance. If it was possible and practical, then I
    would use it.
    Don't spend your energy fighting with me (one-side fights: only on
    USENET :), write a PEP and find good arguments for it.
    I dont intend to, I'm glad there was a misunderstanding and sorry I
    misunderstood (hope thats parseable).

    Maybe there will be a PEP on this someday, but it'll be harder to do
    without evidence that it works well in the real world first.


    -Geoff Howland
    http://ludumdare.com/
  • Christos TZOTZIOY Georgiou at Aug 23, 2003 at 8:22 pm
    On Sat, 23 Aug 2003 19:22:02 GMT, rumours say that Geoff Howland
    <ghowland at lupineNO.SPAMgames.com> might have written:
    I dont intend to, I'm glad there was a misunderstanding and sorry I
    misunderstood (hope thats parseable).
    No harm done, thank you for your reply :). I hoped it was only a matter
    of temporary irritation on your side, and I was thankfully correct;
    otherwise I wouldn't bother to reply, to be sincere...

    Cheers!
    --
    TZOTZIOY, I speak England very best,
    Microsoft Security Alert: the Matrix began as open source.
  • Terry Reedy at Aug 23, 2003 at 11:16 pm
    "Geoff Howland" <ghowland at lupineNO.SPAMgames.com> wrote in message
    news:veefkvs764jl56ub2b0bt4cn4lekcv0mhf at 4ax.com...
    On Sat, 23 Aug 2003 21:56:08 +0300, Christos "TZOTZIOY" Georgiou
    wrote:
    [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.
    I am sorry, Geoff, but I can't understand how you perceived my post
    as
    insulting. If I did understand a way, I would apologise. I just
    snipped stuff in order to make my post shorter, according to
    netiquette.
    How can the phrase inside the brackets seem insulting to you?
    Geoff,
    please justify your clause, and I will gladly apologise.
    If you didn't mean it as insulting, than I am very sorry for taking it
    so and responding in the way I did.

    I saw it as I was being told that I am ignoring the good design
    philosophies of Python, and as such I should move on to another
    language. I have been told exactly this thing before (without being
    mistaking) so I suppose I am more sensitive to it than I would have
    been had I not had it said before.

    Sorry for misunderstanding you and becoming upset about it. :)
    Is this really the way this group is going to continue?
    I don't know, I can speak for myself only. How many people have
    responded to you this "way" to make you wonder about the whole
    group?
    Maybe 2 here, to more or lesser degrees. Probably about 5 times on
    python IRC channels.
    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.
    This is the deal, indeed; for example, I would enjoy very much
    generator
    comprehensions in the language, and yet they were rejected.
    Exactly, and as long as it's ok to bring them up, then all is well. I
    was just feeling like I was being rebuked for doing so. In
    retrospect, I probably should have just not responded at all to the
    thread portion that I felt that way about, as other people were giving
    me answers I thought were completely even.

    I do appreciate Python's design decisions. It's what keeps it from
    becomming the things I dont like about Perl, where that does not seem
    to be the case. However, I still like having the rope to shoot myself
    in the foot if I so desire, but if it doesnt exist I'll get by without
    it. :)
    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.
    My reply came to your specific feature request, ie Python allowing
    you
    to modify the base types; your asking if *any* feature request is
    disallowed is not justified. I consider your question similar to
    the
    following dialog:

    - Can I have cherry pie with my meal?
    - No, because the cook has decided it does not match with your
    meal,
    which is fish.
    - So no one is allowed to ask for dessert here?
    Well, this was because I took your post as hostility. I'm not sure I
    was out there in interpretting this way, as usually telling someone to
    "go somewhere else" when they inquire about things is meant that
    way.
    I believe that the symbolism is childish, and this indeed you might
    find
    it insulting, although it isn't. I am not as fluent in English as
    I
    would like, so this is my way to express the general feeling I got
    from
    your reply; I call it "black-and-white", or "ping-pong", lacking a
    better English word, and describes a two-way communication where a
    disagreement on the one side is perceived magnified as total
    rejection
    on the other side.
    Im fine with the things being one way or another, no problems at all
    with it. I understand why base types arent allowed to be modified,
    cause while you could do it without damaing things, it would be a lot
    more likely that things would be damaged over time and you might never
    know you're including a module that changes behavior. It makes sense.
    That doesn't mean it wouldnt be useful, which is why I was
    inquiring.
    If it was possible, I'd probably do it because of it's usefulness. If
    it became a problem later, I could correct that. I am flexible that
    way, it is probably a good thing Guido and the Python community that
    helps design Python is not. Checks and balances.

    As long as it's still ok to inquire.

    I think the last thing that was really brought up in this "how dare
    you" type style was someone inquiring about protecting their code from
    people reading it. Some people near-flamed the guy for asking how to
    do this, and I think it is ridiculous. Everyone has their own
    purposes for tools, so my ire was up. :)
    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.
    What should it matter what you mind then? It's Guido's language.
    Either we both are allowed to say our minds, or not. My opinion is
    as
    important as yours. Keep that in mind, please.
    Sure, but you were answering a question and saying "no" based on your
    opinions. That's tangential to the question, which is that I want to
    do something. That it's not possible is topical. That
    Guido/PythonLabs doesnt approve is topical, in the sense of a style
    guide. That you don't approve is topical on an advice level, but not
    on a "how do I do this" level.

    Thats my view of it, and since I was thinking you were saying I should
    "move on to another language for not liking everything exactly as it
    is now", then I took it as a judgement placement, rather than advise.
    Again, my misunderstanding and my appology.
    The fact is, the subject has been brought up in the past, and it
    has
    been skipped. I am not sure if has been rejected, so you might
    have a
    chance. If you are as warm about this subject as you seem to be,
    write
    a PEP; my vote will probably be positive. But Guido is the one to
    convince, and he listens; my experience so far has shown that he
    never
    replies the way you do, and that is good.

    This URL should be useful:
    http://www.python.org/peps/pep-0001.html
    I actually wanted to do a proof of concept and try it before writing a
    PEP. Cause if it turns out to suck in practice, why bother with the
    PEP? I think now I would have to change the Python C code in order to
    try it, and that isnt acceptable to me as I wouldnt be able to really
    put it into effect in the real world and see if it works.

    I'm all for putting in the time to write and push a PEP if I think
    something is really worth it and I have proof in my own eyes. I'm
    also accepting if it gets rejected because it doesn't fit with the
    language. So far I haven't gotten to a point where I am confident
    enough about something I think should work a different way to do this.
    Maybe someday it will happen, maybe it wont. I'd like to help, but
    dont want to make suggestions that aren't really helpful until I'm
    convinced myself that they are.
    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.
    Your last statement is unjustified too, and "black-and-white",
    assuming
    hidden meanings in my words. Geoff, I am picking my words very
    carefully because I don't want to make you jump to the ceiling with
    rage. Please read, don't assume.
    The difficulties of reading text. I showed this message to 2 other
    people, and they also thought it was telling me off instead of just
    explaining something to me. However, I still appologize for
    misreading your intentions and my response.
    My sentence was a practical (and respectful!) suggestion; Ruby
    already
    has what you want, and you like it, so why not use it, since the
    Python
    community (and Guido most of all) are against such a modification?
    Did
    you do a research in older newsgroup threads before posting?
    Yeah, I searched around for about 6 hours before posting this, also
    poking around in different books and the python interpretter. I
    didn't find this topic covered, but sometimes it's very hard to find
    things with common words like: python, dict, modification/override,
    etc.

    Ruby is a great language, but there are a couple reasons it wont be
    used in this circumstance. If it was possible and practical, then I
    would use it.
    Don't spend your energy fighting with me (one-side fights: only on
    USENET :), write a PEP and find good arguments for it.
    I dont intend to, I'm glad there was a misunderstanding and sorry I
    misunderstood (hope thats parseable).

    Maybe there will be a PEP on this someday, but it'll be harder to do
    without evidence that it works well in the real world first.


    -Geoff Howland
    http://ludumdare.com/
  • Terry Reedy at Aug 23, 2003 at 11:46 pm
    "Geoff Howland" <ghowland at lupineNO.SPAMgames.com> wrote in message
    news:veefkvs764jl56ub2b0bt4cn4lekcv0mhf at 4ax.com...
    In retrospect, I probably should have just not responded at all to the
    thread portion that I felt that way about, as other people were giving
    me answers I thought were completely even.
    An excellent idea (which I generally try to practice myself).

    As for the Ruby suggestion: It is precisely because we are generally
    pragmatists and not everyone-should-always-program-in-Python fanatics
    that someone occasionally suggests that a particular person might
    (repeat, might) find another language more suitable. The canonical
    example is people distressed by naked code unwrapped by redundant
    braces. If they can't adjust and won't use 'weaning' braces ('#{' and
    '#}'), then they should use a language that better fits their mindset.

    As for 'reasonable' idea rejection: There is effectively no limit to
    what people can collectively think up, and as the community expands,
    the number and breadth of ideas also expands. One of Guido's main
    jobs now is to reject most ideas for 'improvement', no matter how
    'reasonable' in isolation. If your particular wish should remain
    ungranted a year from now, welcome to the club.

    Terry J. Reedy
  • Geoff Howland at Aug 24, 2003 at 1:50 am

    On Sat, 23 Aug 2003 19:46:42 -0400, "Terry Reedy" wrote:
    An excellent idea (which I generally try to practice myself).
    It's a work in progress on my side. :)
    As for the Ruby suggestion: It is precisely because we are generally
    pragmatists and not everyone-should-always-program-in-Python fanatics
    that someone occasionally suggests that a particular person might
    (repeat, might) find another language more suitable. The canonical
    example is people distressed by naked code unwrapped by redundant
    braces. If they can't adjust and won't use 'weaning' braces ('#{' and
    '#}'), then they should use a language that better fits their mindset. Agreed.
    As for 'reasonable' idea rejection: There is effectively no limit to
    what people can collectively think up, and as the community expands,
    the number and breadth of ideas also expands. One of Guido's main
    jobs now is to reject most ideas for 'improvement', no matter how
    'reasonable' in isolation. If your particular wish should remain
    ungranted a year from now, welcome to the club.
    I'm glad that he is limiting things. Perhaps my plan would not have
    worked out well anyway, but I was interested in giving it a shot.
    Since it's not possible, I'll think up some other less hacky slightly
    more verbose way to handle the issues.


    -Geoff Howland
    http://ludumdare.com/
  • Christos TZOTZIOY Georgiou at Aug 24, 2003 at 3:22 am
    On Sun, 24 Aug 2003 01:50:01 GMT, rumours say that Geoff Howland
    <ghowland at lupineNO.SPAMgames.com> might have written:
    I'm glad that he is limiting things. Perhaps my plan would not have
    worked out well anyway, but I was interested in giving it a shot.
    Since it's not possible, I'll think up some other less hacky slightly
    more verbose way to handle the issues.
    Geoff, since you invested already some time and energy on this thread,
    perhaps you should give it a shot, even if it requires some C fiddling.
    I did a research on google and it seems I got luckier than you:

    http://groups.google.com.gr/groups?selm=mailman.1056959572.10194.python-list at python.org

    I also found that the links do not seem to work at this moment in time,
    so a little more searching produced this:

    http://www.amk.ca/diary/2003/03/28.html
    - search for intrinsics in the page

    and then check this (a very long url):

    http://tinyurl.com/kzq6

    which is the python slide show for Pycon 2003. So you can address JP
    Calderone and ask for the intrinsics.c code.
    --
    TZOTZIOY, I speak England very best,
    Microsoft Security Alert: the Matrix began as open source.
  • Jeremy Bowers at Aug 24, 2003 at 7:53 pm

    On Sun, 24 Aug 2003 01:50:01 +0000, Geoff Howland wrote:
    Since
    it's not possible, I'll think up some other less hacky slightly more
    verbose way to handle the issues.
    Well, if this is internal code only, you can always simply do

    from MyDictClassThiny import D

    a = D('a', 'b', 'c', 'd')



    or whatever syntax you can cook up in Python that you might desire.

    The other route you might consider, again for internal code only, is just
    biting the bullet and writing a quick code pre-processor that converts {}
    into a call to your class instead. (Getting it to understand {a: 2}, etc,
    would not be hard.)

    The odds of the general Python language supporting what you are looking
    for are slim to none, but you aren't necessarily stuck with *pure* Python
    if you've got group resources. Personally I'd recommend the pre-processor,
    because it could be run separately later to produce "pure" Python which
    could be useful, rather then hacking the C, which will never be generally
    useful. The pre-processor is pretty easy to write here.

    You might also consider taking a little time a few weeks into the project
    and experimenting with just using the pre-processor output directly. You
    might find the perceived advantages failed to materialize. (Or not.)
  • Greg Ewing at Aug 26, 2003 at 4:32 am

    Terry Reedy wrote:
    If your particular wish should remain
    ungranted a year from now, welcome to the club.
    Careful, or you'll have him wishing his wish would
    not be granted, and crashing the universe. :-)

    Greg
  • Geoff Howland at Aug 23, 2003 at 11:29 am

    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/
  • Robert Kern at Aug 23, 2003 at 1:56 pm
    In article <ckjekvcm6pf4hhq59ro08p20gk6lf9himp at 4ax.com>,
    Geoff Howland <ghowland at lupineNO.SPAMgames.com> 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
    kern at caltech.edu

    "In the fields of hell where the grass grows high
    Are the graves of dreams allowed to die."
    -- Richard Harter
  • Geoff Howland at Aug 23, 2003 at 4:37 pm

    On Sat, 23 Aug 2003 13:56:13 +0000 (UTC), kern at taliesen.caltech.edu (Robert Kern) wrote:

    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
    This is very cool, I've never looked at this before. Will be a
    helpful learning to to see how Python does things. Thanks! :)
    Reading the Language Reference can help a lot, too.
    I searched around in it, didnt read it where I wasnt finding answers.
    Mostly just found the grammar and a little explanation on the parsing,
    but not the way it kicks off commands based on them for these tokens.
    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.
    I can definitely understand that point of view, though if it stays
    restricted to the module you are importing it into, it doesn't seem
    like it would be very destructive. It would also aid in making other
    types of special purpose languages out of Python itself (instead of
    having to create parsers or something).

    True, could lead to messiness and confusion, but also could lead to
    beauty and elegance. Just a question of how much rope it's acceptable
    to be given.
    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 not actually the hardship of doing this, there is also the
    conversion of everything that doesn't create MyDict by default. I
    would have to keep converting them to perform the same manipulations,
    or other functions (add is only an important example, others could be
    handy as well).

    Now I will need additional lines to do this, or make the lines that
    exist more complicated. It's not undue hardship in a lot of ways, but
    it would be nice not to have to and be able to keep the characters
    used to a minimum. Espcially when trying to write sub-50 line scripts
    and such.
    If you're still not convinced, ask yourself these questions:
    I actually feel confident I would be happy with my provided answers as
    real functionality. I don't believe Python will be changed to allow
    that, and that is fine with me. I just wanted to know if it could be
    done the way Python is now.
    * 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?
    Yes and yes.

    It is possible, if this were possible, to only make this work for
    classes that imported it if they so desired I expect. Explicitly
    requested only, etc.
    - On every previously existing object with the base type?
    No, they're already defined. Unless my understanding of the way types
    are done is lacking, and they are referencing the same base object
    code, and then maybe yes to this as well, but it would be passive.
    - In just the one module? or others which import it? or also in
    modules imported after the one with the subclass?
    In the module, and any that import it. It fails to be useful in
    making things clean-and-neat if in order to make a clean-and-neat
    script you have to first have a bunch of stuff that modifies the
    language norms.
    * How does your choice above work with code compiled on-the-fly with
    eval, exec or execfile?
    It would depend on how Python allowed this change to work. If it did
    it the way "I imagine" it would, then the change would effect all of
    these circumstances.
    * How do you deal with multiple subclasses being defined and registered?
    If they re-wrote the same thing and didn't just augment it (or
    overwrote each other), then I would expect them to clobber each other.
    Problems could ensue.

    However, why isn't having {} + {} or [].len() part of the language
    anyway? If it was, people wouldnt have to keep writing their own.

    {} + {} doesnt have to solve ALL cases, which is why I'm assuming it
    isnt already implemented as [] + [] is. It just has to solve the
    basic case and provide the mechanism for determining the difference.
    Ex, key clobbering add, and an intersect() function to see what will
    be clobbered and do something about it if you care.

    Isn't it better to have some default solution than to have none and
    everyone keeps implementing it themselves anew every time?

    For the [].len() type things, this is obviously a matter of taste, and
    I have always been ok with len([]), but in trying to get team mates to
    work with Python I have to concede that [].len() is more consistent
    and a good thing. Same for other builtins that apply.
    * 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)
    I am actually interested in new features than modifying current ones,
    but I suppose you would have this ability as well since you have
    access.

    I would say if you break the initialization or any other methods of
    accessing the type in a default way, then you have just given yourself
    broken code. No one other function will work properly that uses it
    and didn't expect to.

    You will see it doesn't work, and stop. I didn't say I wanted to
    change ALL the behavior of the language, I just wanted to add features
    that dont currently exist and I think should.
    * Can I get a real dict again if wanted to?
    Save it, dont clobber the original out of existance. The coder could
    mess this up (more rope).
    * 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?
    There could be module limitations, but when I imagined this it was
    globally reaching. I believe that as long as you add features, or any
    changes you make dont break things, then you will be safe. If you
    mess with features that exist then you will break things and your
    programs will not work.

    This seems natural enough to me. You ARE changing a default behavior,
    there are risks, but if you dont change things that other functions
    use (pre-existing methods), then you are safe.
    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.
    It seems the changes would have to be to the Python source, and I dont
    want to make a new Python. I dont even want to "change" Python, I
    want to augment it. I think these are reasonable additions, and I'm
    sure I missed the discussions on why they aren't there now.

    There may be very good reasons, and I could end up retracting my
    desired feature set because of them, but I still wanted to see if I
    could make it work for my own code.
    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?
    I think my answers above are sound. If it worked the way I hoped it
    might, you could change things on a global scale and you still
    wouldn't break anything.
    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.
    I never had a problem with this myself, but people are different. I
    have a great team, everyone has their own opinions. No need to
    belittle them for differing.

    Some people never get over the whitespacing. It's just the way the
    people work. No need to see them as flawed. :)


    -Geoff Howland
    http://ludumdare.com/
  • Terry Reedy at Aug 23, 2003 at 5:39 pm
    "Geoff Howland" <ghowland at lupineNO.SPAMgames.com> wrote in message
    news:km4fkv8qbbge3mvckv5gsim9amq59qvohb at 4ax.com...
    For the [].len() type things, this is obviously a matter of taste
    There is also history (and backwards compatibility). Once upon a
    time, neither strings nor tuples had methods, so neither 'abc'.len()
    nor (1,2,3).len() would have been possible.

    With respect to {}+{}. An in-place version of this is currently
    spelled {}.update({}). Yes, more chars to type, but also more
    'honest' in not implying symmetry between the two dicts. As the name
    suggests, duplicate key with new value overrides previous value.

    Terry J. Reedy
  • Geoff Howland at Aug 23, 2003 at 6:09 pm

    On Sat, 23 Aug 2003 13:39:15 -0400, "Terry Reedy" wrote:
    "Geoff Howland" <ghowland at lupineNO.SPAMgames.com> wrote in message
    news:km4fkv8qbbge3mvckv5gsim9amq59qvohb at 4ax.com...
    For the [].len() type things, this is obviously a matter of taste
    There is also history (and backwards compatibility). Once upon a
    time, neither strings nor tuples had methods, so neither 'abc'.len()
    nor (1,2,3).len() would have been possible.
    Thanks for the info. Always good to know history, and sometimes hard
    to find with the glut of common information repeated on the net
    (finding the same function definition pages over and over while
    looking for something the first one you found didn't have :) ).
    With respect to {}+{}. An in-place version of this is currently
    spelled {}.update({}). Yes, more chars to type, but also more
    'honest' in not implying symmetry between the two dicts. As the name
    suggests, duplicate key with new value overrides previous value.
    What's really the problem with a + sugar though? Currently there is
    no sugar, and update() really all there is to it.

    This is a little more pronounced when doing slightly more complex
    things like finding the intersection to things. I wouldn't be opposed
    to less operators, but at least having the functions.

    {}.keys().intersect({}.keys)

    Something like that, and the reverse. I belevie there is a PEP for
    sets around, maybe that will fix this problem. Unless it doesn't mesh
    with any of these other containers well.


    -Geoff Howland
    http://ludumdare.com/
  • Mel Wilson at Aug 31, 2003 at 3:28 pm
    In article <e6bfkvsnro96db74j8en20tuqm0tml23lr at 4ax.com>,
    Geoff Howland wrote:
    On Sat, 23 Aug 2003 13:39:15 -0400, "Terry Reedy" wrote:
    With respect to {}+{}. An in-place version of this is currently
    spelled {}.update({}). Yes, more chars to type, but also more
    'honest' in not implying symmetry between the two dicts. As the name
    suggests, duplicate key with new value overrides previous value.
    What's really the problem with a + sugar though? Currently there is
    no sugar, and update() really all there is to it.
    There's no single clear idea on how that sugar should
    taste, particularly when the operands have keys in common.

    Personally, the applications I've written so far would
    like dictionary addition d+u to work like

    for k in u.keys():
    d[k] = d.get (k, additive_identity) + u[k]

    where additive_identity is a magical value that's 0 working
    with numbers, [] with lists, () with tuples and '' with
    strings. In real life I'd catch the key errors instead.

    But those are yesterdays programs. If you asked me to
    guarantee that tomorrows program would use this, I'd refuse.

    Regards. Mel.
  • Duncan Booth at Sep 8, 2003 at 12:24 pm
    mwilson at the-wire.com (Mel Wilson) wrote in news:oQhU/ks/KXNd089yn at the-
    wire.com:
    Personally, the applications I've written so far would
    like dictionary addition d+u to work like

    for k in u.keys():
    d[k] = d.get (k, additive_identity) + u[k]

    where additive_identity is a magical value that's 0 working
    with numbers, [] with lists, () with tuples and '' with
    strings. In real life I'd catch the key errors instead.
    FWIW, Your 'magical value' isn't actually terribly magical, it is easily
    defined with a few lines of Python:
    class AdditiveIdentityClass:
    def __coerce__(self, other):
    return type(other)(), other

    additive_identity = AdditiveIdentityClass()
    additive_identity + 42
    42
    additive_identity + "urk!"
    'urk!'
    additive_identity + (1,2,3)
    (1, 2, 3)
    additive_identity + { 1:0 }
    Traceback (most recent call last):
    File "<pyshell#34>", line 1, in ?
    additive_identity + { 1:0 }
    TypeError: unsupported operand types for +: 'dict' and 'dict'
    [ 5 ] + additive_identity
    [5]
    3 - additive_identity
    3

    --
    Duncan Booth duncan at rcp.co.uk
    int month(char *p){return(124864/((p[0]+p[1]-p[2]&0x1f)+1)%12)["\5\x8\3"
    "\6\7\xb\1\x9\xa\2\0\4"];} // Who said my code was obscure?
  • Mel Wilson at Sep 12, 2003 at 2:07 am
    In article <Xns93F084E3691FDduncanrcpcouk at 127.0.0.1>,
    Duncan Booth wrote:
    mwilson at the-wire.com (Mel Wilson) wrote in news:oQhU/ks/KXNd089yn at the-
    wire.com:
    [ ... ]
    where additive_identity is a magical value that's 0 working
    with numbers, [] with lists, () with tuples and '' with
    strings. In real life I'd catch the key errors instead.
    FWIW, Your 'magical value' isn't actually terribly magical, it is easily
    defined with a few lines of Python:
    class AdditiveIdentityClass:
    def __coerce__(self, other):
    return type(other)(), other
    Cute!

    Thanks. Mel.
  • Robert Kern at Aug 24, 2003 at 1:54 am
    In article <km4fkv8qbbge3mvckv5gsim9amq59qvohb at 4ax.com>,
    Geoff Howland <ghowland at lupineNO.SPAMgames.com> writes:
    On Sat, 23 Aug 2003 13:56:13 +0000 (UTC), kern at taliesen.caltech.edu
    (Robert Kern) wrote:
    [snip]
    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 not actually the hardship of doing this, there is also the
    conversion of everything that doesn't create MyDict by default. I
    would have to keep converting them to perform the same manipulations,
    or other functions (add is only an important example, others could be
    handy as well).

    Now I will need additional lines to do this, or make the lines that
    exist more complicated. It's not undue hardship in a lot of ways, but
    it would be nice not to have to and be able to keep the characters
    used to a minimum. Espcially when trying to write sub-50 line scripts
    and such.
    I understand this feeling. In the NumPy world, we have the same problem
    with subclassing arrays. The builtin functions still return regular
    arrays.

    One particular type of solution is often possible. For example, making
    an __add__ method for dicts probably doesn't require any other new
    methods, just the normal dict ones (copy, update). That is, it doesn't
    require the other object to be MyDict, just a normal dict. So you can
    write:

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

    Especially for the situations you are considering, where you are only
    adding functionality, not changing the way other methods work, this will
    often be a viable way of doing what you want.
    If you're still not convinced, ask yourself these questions:
    I actually feel confident I would be happy with my provided answers as
    real functionality. I don't believe Python will be changed to allow
    that, and that is fine with me. I just wanted to know if it could be
    done the way Python is now.
    The point of this exercise is to clarify the details what you actually
    want, try to square them with the current architecture and each other,
    and finally to show why they aren't there now.
    * 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?
    Yes and yes.

    It is possible, if this were possible, to only make this work for
    classes that imported it if they so desired I expect. Explicitly
    requested only, etc.
    Not in any clean way. See below.
    - On every previously existing object with the base type?
    No, they're already defined. Unless my understanding of the way types
    are done is lacking, and they are referencing the same base object
    code, and then maybe yes to this as well, but it would be passive.
    The question is "do you really want this?" It would interfere with other
    modules in a very invasive way and according to what you say below is
    not what you want.
    - In just the one module? or others which import it? or also in
    modules imported after the one with the subclass?
    In the module, and any that import it. It fails to be useful in
    making things clean-and-neat if in order to make a clean-and-neat
    script you have to first have a bunch of stuff that modifies the
    language norms.
    I think this is impossible without taking a performance hit in the
    construction of all object with a builtin type. Every internal call to
    PyDict_New, PyList_New, etc. would have to check the registry and
    somehow know what module it is being called from. There would have to be
    a reworking of the internals to give the Py<Object>_New functions that
    kind of information. And you get a performance hit even if you don't
    subclass builtin types.

    And if you do subclass in your module, just for internal use, how can
    you import this module into another without affecting it as well? That
    is, you only want what the module does, not the redefinition of dicts?
    * How does your choice above work with code compiled on-the-fly with
    eval, exec or execfile?
    It would depend on how Python allowed this change to work. If it did
    it the way "I imagine" it would, then the change would effect all of
    these circumstances.
    I don't think it works the way you imagine. I think there would have to
    be even more reworking of the way these work to pass in the information
    that the exec'd code should use the redefinitions in the current module.
    * How do you deal with multiple subclasses being defined and registered?
    If they re-wrote the same thing and didn't just augment it (or
    overwrote each other), then I would expect them to clobber each other.
    Problems could ensue.
    This is where I say "too much rope."
    However, why isn't having {} + {} or [].len() part of the language
    anyway? If it was, people wouldnt have to keep writing their own.

    {} + {} doesnt have to solve ALL cases, which is why I'm assuming it
    isnt already implemented as [] + [] is. It just has to solve the
    basic case and provide the mechanism for determining the difference.
    Ex, key clobbering add, and an intersect() function to see what will
    be clobbered and do something about it if you care.

    Isn't it better to have some default solution than to have none and
    everyone keeps implementing it themselves anew every time?
    Unless the default solution is the one clear way to do it, no. Since it
    only takes a few lines to implement in any one way that you might want
    to do it, there is very little incentive to make the default way one of
    them. You want clobbering; I'll probably want the values added to each
    other as in a sparse array.

    For the same reason, the Python standard library doesn't have a priority
    queue implementation. There are so many different ways to write a
    priority queue with different behaviors, tradeoffs, and applications.
    Since there are all pretty easy to implement in a few number of lines,
    there is no incentive to include a default one in the standard library.
    For the [].len() type things, this is obviously a matter of taste, and
    I have always been ok with len([]), but in trying to get team mates to
    work with Python I have to concede that [].len() is more consistent
    and a good thing. Same for other builtins that apply.
    Terry explains the historical reasons very well. I would also add that
    the "len(obj) calls obj.__len__()" rule enforces a consistency among
    user-defined classes and types. The canonical way to report a length is
    to define a __len__ method, and the canonical way to get a length is to
    call len(obj). If this were not the case, objects would be defining
    .len(), .length(), .getLength(), .number(), .cardinality(), etc.
    * 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)
    I am actually interested in new features than modifying current ones,
    but I suppose you would have this ability as well since you have
    access.

    I would say if you break the initialization or any other methods of
    accessing the type in a default way, then you have just given yourself
    broken code. No one other function will work properly that uses it
    and didn't expect to.
    Again, "too much rope."
    You will see it doesn't work, and stop. I didn't say I wanted to
    change ALL the behavior of the language, I just wanted to add features
    that dont currently exist and I think should.
    I, for one, rarely ever subclass the builtin types to add something
    orthogonal to the original methods. I'm usually modifying the behavior
    of current methods. There's no clean way for an implementation to know
    this upon registry and raise an error.
    * Can I get a real dict again if wanted to?
    Save it, dont clobber the original out of existance. The coder could
    mess this up (more rope).
    * 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?
    There could be module limitations, but when I imagined this it was
    globally reaching. I believe that as long as you add features, or any
    changes you make dont break things, then you will be safe. If you
    mess with features that exist then you will break things and your
    programs will not work.

    This seems natural enough to me. You ARE changing a default behavior,
    there are risks, but if you dont change things that other functions
    use (pre-existing methods), then you are safe.
    This restriction really limits the usefulness of the feature. Compare
    the changes that would have to be made at the architecture level to the
    drawbacks of using MyDict({}).
    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.
    It seems the changes would have to be to the Python source, and I dont
    want to make a new Python. I dont even want to "change" Python, I
    want to augment it. I think these are reasonable additions, and I'm
    sure I missed the discussions on why they aren't there now.

    There may be very good reasons, and I could end up retracting my
    desired feature set because of them, but I still wanted to see if I
    could make it work for my own code.
    At the Python prompt, "import this".
    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?
    I think my answers above are sound. If it worked the way I hoped it
    might, you could change things on a global scale and you still
    wouldn't break anything.
    Well, Python isn't architectured the same way that Ruby is. There are
    fundamental problems in doing what you want.
    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.
    I never had a problem with this myself, but people are different. I
    have a great team, everyone has their own opinions. No need to
    belittle them for differing.

    Some people never get over the whitespacing. It's just the way the
    people work. No need to see them as flawed. :)
    No belittling was intended. I just wanted to express that I just don't
    see the sense in it, and that if I had to work with such a team, I would
    be tearing my hair out. I lose enough hair interfacing with FORTRAN,
    thank you very much. :-)

    Preferring [].len() to len([]) is one thing, claiming it's intrinsically
    more OO is another.
    -Geoff Howland
    http://ludumdare.com/
    --
    Robert Kern
    kern at caltech.edu

    "In the fields of hell where the grass grows high
    Are the graves of dreams allowed to die."
    -- Richard Harter
  • Andrew Dalke at Aug 24, 2003 at 3:38 am

    Geoff Howland:
    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.
    As others have pointed out, you can use obj.__len__() if you really
    want to use it as a method.

    I admit this looks ugly. Hoever, there is a benefit to this approach.
    I am free to define any methods I want and any attributes on want,
    so long as the names don't both start and end with "__", which is
    reserved for the language.

    Compare this to, say, Ruby, where it takes extra knowledge to
    know that 'initialize', 'id', 'method', 'to_a', 'hash', and others have
    special meanings. Suppose I had a HashBrown controller, for
    a machine for making hash browns. I couldn't do the equivalent
    of

    possible_methods = ["soft", "crunchy", "southwestern"]

    class AbstractHashBrownController:
    def __init__(self, method, interface):
    assert method in possible_methods
    self.method = method
    self.id = interface.acquire_machine_identifier()

    def initialize(self):
    """Initialize hash-brown systems (eg, light the gas)"""

    def hash(self):
    """chop up the potatoes"""
    ....

    While this example is a bit extreme, it worries me that I need
    to remember all the methods names reserved by the language,
    and that if the base Object adds new methods then my code
    might accidentally break in consequence.

    Most languages don't need that many special variables,
    so I find it appropriate that when they are needed then I
    need to do a bit extra work for them. At a different extreme
    is Perl, where builtins don't have a leading sigil while variables
    do (or can), so if I have $hash then the language can add 'hash'
    and not affect anything. I find that too extreme because most
    things are user-defined code, so it makes the common case
    more complicated.

    Python then gets rid of the problem by defining builtins for
    accessing those __special__ methods, so they are rarely
    needed except for defining. (Though it then gains the problem
    that you need to know id uses __id__, bool uses __len__
    and __nonzero__, + uses __add__ and __radd__ and
    __coerce__, etc.)

    Andrew
    dalke at dalkescientific.com
  • John Roth at Aug 23, 2003 at 11:53 am
    "Geoff Howland" <ghowland at lupineNO.SPAMgames.com> wrote in message
    news:mtqdkv8sdrmgrn02vugnbpuhtjsgel3ohb at 4ax.com...
    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.
    Literals (and those are literals) are hard coded at the parser level,
    and are not availible to change - unless, of course, you want to
    change the source.

    John Roth
  • Geoff Howland at Aug 23, 2003 at 3:53 pm

    On Sat, 23 Aug 2003 07:53:44 -0400, "John Roth" wrote:


    "Geoff Howland" <ghowland at lupineNO.SPAMgames.com> wrote in message
    news:mtqdkv8sdrmgrn02vugnbpuhtjsgel3ohb at 4ax.com...
    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.
    Literals (and those are literals) are hard coded at the parser level,
    and are not availible to change - unless, of course, you want to
    change the source.
    Dont want to do that, thanks.


    -Geoff Howland
    http://ludumdare.com/
  • Michele Simionato at Aug 23, 2003 at 3:18 pm
    Geoff Howland <ghowland at lupineNO.SPAMgames.com> wrote in message news:<04cekv0s6ghjtuhl5j2gph7ltobdb5rsam at 4ax.com>...
    On 23 Aug 2003 07:02:53 GMT, "OKB (not okblacke)" 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.
    MicheleSimionato at libero.it
    http://www.phyast.pitt.edu/~micheles
    --- Currently looking for a job ---
  • Geoff Howland at Aug 23, 2003 at 4:12 pm

    On 23 Aug 2003 08:18:49 -0700, mis6 at pitt.edu (Michele Simionato) wrote:

    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)
    Yeah, I got this to work off the bat.
    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).

    len([])

    [].len()

    Both seem to make sense explicitly to me. Currently we use it through
    builtins, but having it as an attribute would also be clear. It's
    duplicated, but at the same time it's consistant.

    Yes I know it makes one version of [] different than others, but if
    you state it is going to happen, then it is known. If it is all new
    functionality, then it wont break old functionality. If you change
    old functionality, you know you are doing it and risking problems.

    Python allows for a lot of different things some people in other
    languages claim is dangerous because it's too free-hand. That doesn't
    make them right, and often I've read statements in the spirit of
    "Python gives you enough rope to let shoot yourself in the foot", and
    it's meant as a good thing. We're all adults here, etc.

    I still think the above things might be good in the language in
    general (not just a specific module change), but I would feel a lot
    more certain after using them for a while in the real world.


    -Geoff Howland
    http://ludumdare.com/
  • Dave Brueck at Aug 23, 2003 at 10:30 am

    On Saturday 23 August 2003 10:12 am, Geoff Howland wrote:
    On 23 Aug 2003 08:18:49 -0700, mis6 at pitt.edu (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
  • Erik Max Francis at Aug 23, 2003 at 7:27 pm

    Geoff Howland wrote:

    On 23 Aug 2003 08:18:49 -0700, mis6 at pitt.edu (Michele Simionato)
    wrote:
    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)
    Yeah, I got this to work off the bat.
    So what's the problem? If you got it to do what you wanted, why would
    you possibly want your personal changes reflected officially in the
    language? Sit back for a moment and think what would happen if
    _everybody_ proceeded this way.

    --
    Erik Max Francis && max at alcyone.com && http://www.alcyone.com/max/
    __ San Jose, CA, USA && 37 20 N 121 53 W && &tSftDotIotE
    / \ Wars may be fought with weapons, but they are won by men.
    \__/ Gen. George S. Patton
  • Geoff Howland at Aug 23, 2003 at 7:31 pm

    On Sat, 23 Aug 2003 12:27:02 -0700, Erik Max Francis wrote:
    Geoff Howland wrote:
    On 23 Aug 2003 08:18:49 -0700, mis6 at pitt.edu (Michele Simionato)
    wrote:
    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)
    Yeah, I got this to work off the bat.
    So what's the problem? If you got it to do what you wanted, why would
    you possibly want your personal changes reflected officially in the
    language? Sit back for a moment and think what would happen if
    _everybody_ proceeded this way.
    I didn't say my personal preferences should become the official
    language. I made arguments for some things I thought were logical
    becoming part of the official language, and that seems fine. We've
    been over the problems with it, and why it is NOT part of the
    language, but it still is a logical argument and was just rejected.

    On my personal goals, that definitely wouldnt be added to the official
    language, I was just looking for a way to make them work for my own
    project. If it was a hack, so be it. If it turned out to not work
    well, I could revert it. It's not possible, so that's fine.

    I'm satisfied with all the answers I've received in this thread and am
    now fully illuminated on the subject.


    -Geoff Howland
    http://ludumdare.com/
  • Terry Reedy at Aug 24, 2003 at 7:20 am
    "> 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().
    One point someone made is summarized by the following contrast:

    collections = (atuple, alist, adict, someothercollection)
    flengths = map(len, collections) #actual
    mlengths = map(lambda obj: gettattr(obj, 'len')(), collections)
    #hypothetical
    # or listcomp equivalents

    Terry J. Reedu
  • Just at Aug 24, 2003 at 7:57 am
    In article <Zi6dnd57h5jI-tWiXTWJkA at comcast.com>,
    "Terry Reedy" wrote:
    "> 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().
    One point someone made is summarized by the following contrast:

    collections = (atuple, alist, adict, someothercollection)
    flengths = map(len, collections) #actual
    mlengths = map(lambda obj: gettattr(obj, 'len')(), collections)
    #hypothetical
    Uh?
    mlengths = map(lambda obj: obj.len(), collections)
    # or listcomp equivalents
    That would be much better than the lambda version:
    mlengths = [x.len() for x in collections]

    Just
  • Dan Bishop at Aug 23, 2003 at 3:56 pm
    Geoff Howland <ghowland at lupineNO.SPAMgames.com> wrote in message news:<mtqdkv8sdrmgrn02vugnbpuhtjsgel3ohb at 4ax.com>...
    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.
    The only way to do that is to modify the C code for the interpreter.

    Otherwise, you'll have to stick with
    class NewDict(dict):
    ... def __add__(self, other):
    ... result = self.copy()
    ... result.update(other)
    ... return result
    ...
    NewDict({1:2}) + NewDict({3:4})
    {1: 2, 3: 4}
  • Scott David Daniels at Aug 23, 2003 at 10:03 pm

    Geoff Howland wrote:
    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 might want to contribute to pypy -- once their work is completed
    we'll have a python written fully in python that will allow you such
    experiments.

    I'm sorry, but I cannot resist complaining a bit about allowing such
    changes as implementable in modules:

    user A likes (and implements) your idea about {} + {}, user B thinks
    you are right, but where the two dictionaries share a coomon key, the
    value shoud be the sum of the two values. Either of these works, but
    modules expecting one will fail with the other. As a result, it seems
    a bad idea to allow modules to make such changes. I do _not_ mean
    that the experiment in redefining {} can/should not be tried, but
    rather the experiment must be environment-wide; it does not isolate
    nicely.

    As a practical matter, I suspect the current feeling is towards fewer,
    rather than more, punctualtion-based expressions -- they are harder to
    look up i na reference document.

    -Scott David Daniels
    Scott.Daniels at Acm.Org
  • Seo Sanghyeon at Aug 24, 2003 at 12:33 am
    Geoff Howland asked:
    (about extending builtin literal types.)

    You _could_ do that in Python 2.2, though it was a bug, not a feature.

    ----
    Python 2.2
    def add(self, key, value):
    self[key] = value
    dict.add = add
    TypeError: can't set attributes of built-in/extension type 'dict'
    object.__setattr__(dict, "add", add) # !!
    x = {}
    x.add(1, 1)
    x
    {1: 1}
    ----

    Don't tell others that I said this.

    Why this is a bug, not a feature? I think that is because Python is not
    Ruby. Another evidence is that this behaviour is _fixed_ in Python 2.3:

    ----
    Python 2.3
    object.__setattr__(dict, "add", add)
    TypeError: can't apply this __setattr__ to type object
    ----

    Obviously somebody put a sanity check there.

    Seo Sanghyeon
  • Michael C. Neel at Aug 25, 2003 at 3:58 pm

    The problem here is that, when looking at d1 + d2, it is not
    obvious what is
    going on. If the same key appears in both d1 and d2, what
    will the resulting
    dict have? The value in d1? The value in d2? Or maybe an
    exception will be
    raised? Different people will have different notions here
    about what is
    "obvious" and "natural".

    "Pick one and make that the standard" may work in some other
    languages, but
    that is usually not how Python's design works. If there is
    not "one obvious
    way", chances are it won't make it into the language. (Of
    course, there are
    exceptions... but this seems to be a rule-of-thumb.)
    Sadly, I think python is taking this too far, and spends more time
    debating operators than advancing the language. This has kept out ?:
    and += from being allowed. And in Geoff's case here, if Python
    supported traditional C++ like operator overloading, then we could have
    the best of both worlds - he doesn't "replace" the builting dict, but
    creates a new dict class and overloads {} and +,- or whatever else he
    wishes.

    Coming up with a solution that everyone likes is not going to happen...
    ever (re: ', '.join([]) ). but we shouldn't rule out something because
    there is not a uniamous vote (if that were so, we would have no join
    method).

    IMHO of cource,
    Mike
  • Skip Montanaro at Aug 25, 2003 at 4:58 pm
    Mike> Sadly, I think python is taking this too far, and spends more time
    Mike> debating operators than advancing the language. This has kept out
    Mike> ?: and += from being allowed.

    Last I looked, += was in the language. I even use it in restricted
    situations. That ?: isn't in the language is probably because no proposals
    have been advanced which fit well enough with the language to sway Guido.

    Skip
  • Michael Chermside at Aug 28, 2003 at 5:56 pm

    Geoff Howland writes:
    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.
    Step back a sec... I didn't find Christos's comments "insulting", and
    I'm sure they weren't intended that way. You've asked a legitimate
    question: "Can I change the behavior of the objects created by literal
    {}, [], "", and ''?". The answer to that question was, "Only if you
    modify the Python interpreter (written in C)."

    Now there are a few places you could go from here. One is that you
    could take the advice of a few folks here and check out Ruby. It's
    another language which is a lot like Python in many ways, but it's
    most significant difference is that it DOES allow programmers to do
    EXACTLY the kind of thing that you are asking for.

    Another thing you could do would be to explain what it is that you
    are trying to achieve, and ask people on this list to suggest
    alternative approaches that WILL work in Python. Perhaps they'll
    say you need to write "Q({...})" in place of "{...}" everywhere and
    that will fix your problem. Or maybe there's some clever metaclass
    trick that will help out. If you want to go this route you should
    try to describe what problem you are trying to solve (eg: "My
    developers all come from a Pascal background, and they keep trying
    to use + and - with dicts as if they were sets."). And then keep an
    open mind about the responses you receive: some will be off-the-mark
    and won't fix your problem, but others will be out-of-the-box and
    WILL fix your problem, just not in the way you had expected.

    The third approach would be for you to ask questions about WHY the
    things you wanted don't work in Python. It's NOT an accident, or
    just that we haven't gotten around to it yet, these were deliberate
    design decisions. Perhaps once you hear the reasoning you'll find
    it doesn't apply to what you're doing, or perhaps you will decide
    that Python as-designed makes sense after all.

    Since you've already started asking some approach-three style
    questions, I will see if I can answer them:
    [] + [] is allowed. Right?

    {} + {} is not allowed.
    That's because it's not clear what to do with {1:'a'} + {1:'b'}.
    Should it result in {1:'a'}? {1:'b'}? {1:['a','b']}? An exception?
    All of these make sense for different applications, and so Guido
    decided to prohibit the whole thing and provide specific methods
    like {}.update() as needed.
    len([]) is allowed.

    [].len() is not allowed.
    Yes it is. It's just spelled a little funny. Try "[].__len__()"
    instead.
    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.
    Well, I don't think so. If Guido wants to do it one way but the
    community consensus is that another way is better, then I think that
    Guido should shut up and go with the community. Guido's personal
    strength is that his approaches very often turn out to make great
    sense, but sometimes only after you've been trying it for a while,
    and NOTHING ever makes sense to ALL users.
    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 only allowed, it's encouraged! Python is open source, so you
    can just grab a copy and try out your ideas. You can even try talking
    someone else into helping you try them out. Submit a patch, and it
    might get accepted. Write a PEP (no coding skill required) and you
    might recruit others to write it for you. An extreme example is
    Stackless Python. YEARS ago, Christian Tismer wanted to try a very
    different approach to managing the call stack in Python. His changes
    never got accepted into the core, but now Stackless exists as a
    separate distribution. And although it took a while, I'd say that
    now Christian probably favors that approach (sorry Christian if I'm
    mis-channeling you here): cPython's approach has some advantages
    (eg: portability), and Stackless has others (eg: microthreads).

    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.
    It wasn't intended that way. Seriously... Python *INTENTIONALLY*
    prohibits you from doing what you are asking for. Ruby is a similar
    language that allows, even encourages it. That's worth pointing out --
    and maybe worth checking out. But as Christos said "with all due
    respect" -- he's presuming that you ARE serious here and DO want
    these features, and he's suggesting one way of getting them.

    -- Michael Chermside

Related Discussions

People

Translate

site design / logo © 2022 Grokbase