quick poll: could int, str, tuple etc. become type objects?

While thinking about metatypes, I had an interesting idea. In PEP 252 and 253 (which still need much work, please bear with me!) I describe making classes and types more similar to each other. In particular, you'll be able to subclass built-in object types in much the same way as you can subclass user-defined classes today. One nice property of classes is that a class is a factory function for its instances; in other words, if C is a class, C() returns a C instance. Now, for built-in types, it makes sense to do the same. In my current prototype, after "from types import *", DictType() returns an empty dictionary and ListType() returns an empty list. It would be nice take this much further: IntType() could return an integer, TupleType() could return a tuple, StringType() could return a string, and so on. These are immutable types, so to make this useful, these constructors need to take an argument to specify a specific value. What should the type of such an argument be? It's not very interesting to require that int(x) takes an integer argument! Most of the popular standard types already have a constructor function that's named after their type: int(), long(), float(), complex(), str(), unicode(), tuple(), list() We could make the constructor take the same argument(s) as the corresponding built-in function. Now invoke the Zen of Python: "There should be one-- and preferably only one --obvious way to do it." So why not make these built-in functions *be* the corresponding types? Then instead of
int <built-in function int>
you would see
int <type 'int'>
but otherwise the behavior would be identical. (Note that I don't require that a factory function returns a *new* object each time.) If we did this for all built-in types, we'd have to add maybe a dozen new built-in names -- I think that's no big deal and actually helps naming types. The types module, with its awkward names and usage, can be deprecated. There are details to be worked out, e.g. - Do we really want to have built-in names for code objects, traceback objects, and other figments of Python's internal workings? - What should the argument to dict() be? A list of (key, value) pairs, a list of alternating keys and values, or something else? - What else? Comments? --Guido van Rossum (home page: http://www.python.org/~guido/)

guido wrote:
+1 from here.
- Do we really want to have built-in names for code objects, traceback objects, and other figments of Python's internal workings?
nope.
- What should the argument to dict() be? A list of (key, value) pairs, a list of alternating keys and values, or something else?
how about supporting the following: d == dict(d.items()) d == dict(d.keys(), d.values()) and also: d = dict(k=v, k=v, ...) Cheers /F

I'm +1 on the general concept; I think it will make explaining Python easier in the long run. I'm not competent to vote on the details, but I'll complain if something seems too confused to me. Currently in the Decimal class I'm working on, I can take any of the following types in the constructor: Decimal, tuple, string, int, float. I'm wondering whether that approach makes sense, that any "compatible" type should be accepted in an explicit constructor. So for your question about dict(), perhaps any sequence/iterator type that returns 2-element sequences would be be accepted. -- --- Aahz (@pobox.com) Hugs and backrubs -- I break Rule 6 <*> http://www.rahul.net/aahz/ Androgynous poly kinky vanilla queer het Pythonista I don't really mind a person having the last whine, but I do mind someone else having the last self-righteous whine.

On Tue, 5 Jun 2001, Guido van Rossum wrote:
I'm all in favour of this. In fact, i had the impression that you were planning to do exactly this all along. I seem to recall some conversation about this a long time ago -- am i dreaming?
I would love this.
- Do we really want to have built-in names for code objects, traceback objects, and other figments of Python's internal workings?
Perhaps we would only provide built-in names for objects that are commonly constructed. For things like code objects that are never user-constructed, their type objects could be set aside in a module.
- What should the argument to dict() be? A list of (key, value) pairs, a list of alternating keys and values, or something else?
A list of (key, value) pairs. It's the only sensible choice, given that dict.items() is the obvious way to get all the information out of a dictionary into a list. -- ?!ng

Guido van Rossum <guido@digicool.com> wrote,
I like it!
but otherwise the behavior would be identical. (Note that I don't require that a factory function returns a *new* object each time.)
Of course... singletons (which would also break that requirement) are quite useful.
I dont think so. Having easy access to these things might be good but since they are implementation specific it might be best to discourage their use by putting them somewhere more implementation specific, like the newmodule or even sys.
- What should the argument to dict() be? A list of (key, value) pairs, a list of alternating keys and values, or something else?
At a minimum, I'd like to see a list of key/value tuples. I seem to find myself reconstructing dicts from the .items() of other dicts. For 'something else', I'd like to be able to pass keyword arguments to initialize the new dict. Going really crazy, I'd like to be able to pass a dict as an argument to dict()... just another way to spell copy, but combined with keywords, it would be more like copy followed by an update.
- What else?
Well, since you are asking ;) I havnt read the PEP, so perhaps I shouldnt be commenting just yet, but. I'd hope that the built-in types are sub-classable from C as well as from Python. This is most interesting for types like instance, class, method, but I can imagine reasons for doing it to tuple, list, dict, and even int.
Comments?
Fantastic! -- Donald Beaudry Ab Initio Software Corp. 201 Spring Street donb@init.com Lexington, MA 02421 ...Will hack for sushi...

Guido van Rossum wrote:
-1 While this looks cute, I think it would break a lot of introspection code or other code which special cases Python functions for some reason since type(int) would no longer return types.BuiltinFunctionType. If you don't like the names, why not take the change and create a new module which then exposes the Python class hierarchy (much like we did with the exceptions.py module before it was intregrated as C module) ?!
Not really.
- What should the argument to dict() be? A list of (key, value) pairs, a list of alternating keys and values, or something else?
As function, I'd say: take either a sequence of tuples or another dictionary as argument. mxTools already has such a function, BTW. -- Marc-Andre Lemburg CEO eGenix.com Software GmbH ______________________________________________________________________ Company & Consulting: http://www.egenix.com/ Python Software: http://www.lemburg.com/python/

Looks like I'm alone with my uncertain feeling about this move... oh well. BTW, we should consider having more than one contructor for an object rather than trying to stuff all possible options and parameters into one overloaded super-constructor. I've done this in many of my mx extensions and have so far had great success with it (better programming error detection, better docs, more intuitive interfaces, etc.). In that sense, more than one way to do something will actually help clarify what the programmer really wanted. Just a thought... -- Marc-Andre Lemburg CEO eGenix.com Software GmbH ______________________________________________________________________ Company & Consulting: http://www.egenix.com/ Python Software: http://www.lemburg.com/python/

Well, I don't see how someone could be doing introspection on int and be confused when it's not a function -- either you (think you) know it's a function, so you use it as a function without introspecting it, and that continues to work; or you're open to all possibilities, and then you'll introspect it, and then you'll discover what it is.
Yes, but the other ways are spelled as factory functions. Maybe, *maybe* the other factory functions could be class-methods, but don't hold your hopes high. --Guido van Rossum (home page: http://www.python.org/~guido/)

Guido van Rossum wrote:
Ok, let's put it in another way: The point is that your are changing the type of very basic building parts in Python and that is likely to cause failure in places which will most likely be hard to find to fix. Becides we don't really gain anything from replacing builtin functions with classes (to the contrary: we lose some, since we can no longer use the function call optimizations for builtins and have to go through all the generic call mechanism code instead). Also, have you considered the effects this has on restricted execution mode ? What will happen if someone replaces the builtins with special versions which hide some security relevant objects, e.g. open() is a prominent candidate for this. Why not put the type objects into a separate module instead of reusing the builtins ?
No... why make things complicated when simple functions work just fine as factories. Multilpe constructors on a class would make subclassing a pain... -- Marc-Andre Lemburg CEO eGenix.com Software GmbH ______________________________________________________________________ Company & Consulting: http://www.egenix.com/ Python Software: http://www.lemburg.com/python/

Adding the atomic types of python as classes I'm +1 on. Perfomance is a problem for the parser to handle. If you have not already done so I suggest that you look at what MicroSoft .NET is doing in this area. In .NET, for example, int is a class and they have the technology to define the interface to an int and optimize the performace of the none derived cases. Barry

Actually, that is not completely true. There is a "value type" and a class version. The value type is just the bits. The VM has instructions that work in the value type. As far as I am aware, you can not use a derived class with these instructions. They also have the concept of "sealed" meaning they can not be subclassed. Last time I looked, strings were an example of sealed classes. Mark.

"GvR" == Guido van Rossum <guido@digicool.com> writes:
GvR> Now invoke the Zen of Python: "There should be one-- and GvR> preferably only one --obvious way to do it." So why not make GvR> these built-in functions *be* the corresponding types? Then GvR> instead of >> int GvR> <built-in function int> GvR> you would see >> int GvR> <type 'int'> +1 GvR> but otherwise the behavior would be identical. (Note that I GvR> don't require that a factory function returns a *new* object GvR> each time.) GvR> If we did this for all built-in types, we'd have to add maybe GvR> a dozen new built-in names -- I think that's no big deal and GvR> actually helps naming types. The types module, with its GvR> awkward names and usage, can be deprecated. I'm a little concerned about this, since the names that would be added are probably in common use as variable and/or argument names. I.e. At one point `list' was a very common identifier in Mailman, and I'm sure `dict' is used quite often still. I guess this would be okay as long as working code doesn't break because of it. OTOH, I've had fewer needs for a dict builtin (though not non-zero), and easily zero needs for traceback objects, code objects, etc. GvR> There are details to be worked out, e.g. GvR> - Do we really want to have built-in names for code objects, GvR> traceback objects, and other figments of Python's internal GvR> workings? I'd say no. However, we could probably C-ify the types module, a la, the exceptions module, and that would be the logical place to put the type factories. GvR> - What should the argument to dict() be? A list of (key, GvR> value) pairs, a list of alternating keys and values, or GvR> something else? You definitely want to at least accept a sequence of key/value 2-tuples, so that d.items() can be retransformed into a dictionary object. -Barry

It would be hard to see how this would break code, since built-ins are searched *after* all variables that the user defines. --Guido van Rossum (home page: http://www.python.org/~guido/)

"GvR" == Guido van Rossum <guido@digicool.com> writes:
>> I'm a little concerned about this, since the names that would >> be added are probably in common use as variable and/or argument >> names. I.e. At one point `list' was a very common identifier >> in Mailman, and I'm sure `dict' is used quite often still. I >> guess this would be okay as long as working code doesn't break >> because of it. GvR> It would be hard to see how this would break code, since GvR> built-ins are searched *after* all variables that the user GvR> defines. Wasn't there talk about issuing warnings for locals shadowing built-ins (or was that globals?). If not, fergitaboutit. If so, that would fall under the category of "breaking". -Barry

You may be thinking of this: >>> def f(int): def g(): int <stdin>:1: SyntaxWarning: local name 'int' in 'f' shadows use of 'int' as global in nested scope 'g' >>> This warns you when you override a built-in or global *and* you use that same name in a nested function. This code will mean something different in 2.2 anyway (g's reference to int will become a reference to f's int because of nested scopes). But this does not cause a warning: >>> def g(): int = 12 >>> Nor does this: >>> int = 12 >>> So we're safe. --Guido van Rossum (home page: http://www.python.org/~guido/)

[Guido]
I think that it will be difficult to avoid creating a new object under jython because calling a type already directly calls the type's java constructor.
Jython already interprets the arguments to the dict type as alternating key/values:
This behaviour isn't documented on the python side so it can be changed. However, it it is necessary to maintain this API on the java side and we have currently no way to prevent the type constructors from being visible and callable from python. Whatever is decided, I hope jython can keep the current semantics of its dict type. regards, finn

On Tue, 5 Jun 2001, Guido van Rossum wrote:
+1
- Do we really want to have built-in names for code objects, traceback objects, and other figments of Python's internal workings?
I would say to put all of the common constructors in __builtin__, and all of the odd ducks can go into the new module.
- What should the argument to dict() be? A list of (key, value) pairs, a list of alternating keys and values, or something else?
A varargs list of (key,value) tuples would probably be most useful. Since most of these functions, before being classed as constructors, were considered coercion function, I wouldn't be against having it try to do something sensible with a variety of args. -- sdm

Is the intent of using int and friends as constructors instead of just coercion functions that I should (eventually) be able to do this: class NonNegativeInt(int): def __init__(self, val): if int(val) < 0: raise ValueError, "Value must be >= 0" int.__init__(self, val) self.a = 47 ... ? Skip

On 05 June 2001, Guido van Rossum said:
+1 from me too.
Cool!
Probably not, as long as they are accessible somewhere. I could live with either a C-ified 'types' module or shoving these into the 'new' module, although I think I prefer the latter slightly.
- What should the argument to dict() be? A list of (key, value) pairs, a list of alternating keys and values, or something else?
I love /F's suggestion dict(k=v, k=v, ...) but that's icing on the cake -- cool feature, looks pretty, etc. (And *finally* Python will have all the syntactic sugar that Perl programmers like to have. ;-) I think the real answer should be dict(k, v, k, v) like Jython. If both can be supported, that would be swell. Greg -- Greg Ward - Linux geek gward@python.net http://starship.python.net/~gward/ Does your DRESSING ROOM have enough ASPARAGUS?

"GW" == Greg Ward <gward@python.net> writes:
GW> I love /F's suggestion GW> dict(k=v, k=v, ...) One problem with this syntax is that the `k's can only be valid Python identifiers, so you'd at least need /some/ other syntax to support construction with arbitrary hashable keys. -Barry

greg wrote:
note that the python interpreter builds that dictionary for you if you use the METH_KEYWORDS flag...
given that Jython already gives a meaning to dict with more than one argument, I suggest: dict(d) # consistency dict(k, v, k, v, ...) # jython compatibility dict(*[k, v, k, v, ...]) # convenience dict(k=v, k=v, ...) # common pydiom and maybe: dict(d.items()) # symmetry
If both can be supported, that would be swell.
how about: if (PyTuple_GET_SIZE(args)) { assert PyDict_GET_SIZE(kw) == 0 if (PyTuple_GET_SIZE(args) == 1) { args = PyTuple_GET_ITEM(args, 0); if (PyDict_Check(args)) dict = args.copy() else if (PySequence_Check(args)) dict = {} for k, v in args: dict[k] = v } else { assert (PySequence_Size(args) & 0) == 0 # maybe dict = {} for i in range(len(args)): dict[args[i]] = args[i+1] } } else { assert PyDict_GET_SIZE(kw) > 0 # probably dict = kw }

On 06 June 2001, Fredrik Lundh said:
Yikes. I still think that #2 is the "essential" spelling. I think Tim was speaking of #1 when he said we don't need another way to spell copy() -- I'm inclined to agree. I think the fact that you can say int(3) or str("foo") are not strong arguments in favour of dict({...}), because of mutability, because of the overhead of dicts, because we already have the copy module, maybe other factors as well.
and maybe:
dict(d.items()) # symmetry
I think this is massive overloading. Two interfaces to a single function ought to be enough. I for one have long wished for syntactic sugar like Perl's => operator, which lets you do this: %band = { geddy => "bass", alex => "guitar", neil => "drums" } ...and keyword arg syntax is really the natural thing here. Being able to say band = dict(geddy="bass", alex="guitar", neil="drums") would be good enough for me. And it's less mysterious than Perl's =>, which is just a magic comma that forces its LHS to be interpreted as a string. Weird. Greg -- Greg Ward - Linux geek gward@python.net http://starship.python.net/~gward/ If you and a friend are being chased by a lion, it is not necessary to outrun the lion. It is only necessary to outrun your friend.

guido wrote:
+1 from here.
- Do we really want to have built-in names for code objects, traceback objects, and other figments of Python's internal workings?
nope.
- What should the argument to dict() be? A list of (key, value) pairs, a list of alternating keys and values, or something else?
how about supporting the following: d == dict(d.items()) d == dict(d.keys(), d.values()) and also: d = dict(k=v, k=v, ...) Cheers /F

I'm +1 on the general concept; I think it will make explaining Python easier in the long run. I'm not competent to vote on the details, but I'll complain if something seems too confused to me. Currently in the Decimal class I'm working on, I can take any of the following types in the constructor: Decimal, tuple, string, int, float. I'm wondering whether that approach makes sense, that any "compatible" type should be accepted in an explicit constructor. So for your question about dict(), perhaps any sequence/iterator type that returns 2-element sequences would be be accepted. -- --- Aahz (@pobox.com) Hugs and backrubs -- I break Rule 6 <*> http://www.rahul.net/aahz/ Androgynous poly kinky vanilla queer het Pythonista I don't really mind a person having the last whine, but I do mind someone else having the last self-righteous whine.

On Tue, 5 Jun 2001, Guido van Rossum wrote:
I'm all in favour of this. In fact, i had the impression that you were planning to do exactly this all along. I seem to recall some conversation about this a long time ago -- am i dreaming?
I would love this.
- Do we really want to have built-in names for code objects, traceback objects, and other figments of Python's internal workings?
Perhaps we would only provide built-in names for objects that are commonly constructed. For things like code objects that are never user-constructed, their type objects could be set aside in a module.
- What should the argument to dict() be? A list of (key, value) pairs, a list of alternating keys and values, or something else?
A list of (key, value) pairs. It's the only sensible choice, given that dict.items() is the obvious way to get all the information out of a dictionary into a list. -- ?!ng

Guido van Rossum <guido@digicool.com> wrote,
I like it!
but otherwise the behavior would be identical. (Note that I don't require that a factory function returns a *new* object each time.)
Of course... singletons (which would also break that requirement) are quite useful.
I dont think so. Having easy access to these things might be good but since they are implementation specific it might be best to discourage their use by putting them somewhere more implementation specific, like the newmodule or even sys.
- What should the argument to dict() be? A list of (key, value) pairs, a list of alternating keys and values, or something else?
At a minimum, I'd like to see a list of key/value tuples. I seem to find myself reconstructing dicts from the .items() of other dicts. For 'something else', I'd like to be able to pass keyword arguments to initialize the new dict. Going really crazy, I'd like to be able to pass a dict as an argument to dict()... just another way to spell copy, but combined with keywords, it would be more like copy followed by an update.
- What else?
Well, since you are asking ;) I havnt read the PEP, so perhaps I shouldnt be commenting just yet, but. I'd hope that the built-in types are sub-classable from C as well as from Python. This is most interesting for types like instance, class, method, but I can imagine reasons for doing it to tuple, list, dict, and even int.
Comments?
Fantastic! -- Donald Beaudry Ab Initio Software Corp. 201 Spring Street donb@init.com Lexington, MA 02421 ...Will hack for sushi...

Guido van Rossum wrote:
-1 While this looks cute, I think it would break a lot of introspection code or other code which special cases Python functions for some reason since type(int) would no longer return types.BuiltinFunctionType. If you don't like the names, why not take the change and create a new module which then exposes the Python class hierarchy (much like we did with the exceptions.py module before it was intregrated as C module) ?!
Not really.
- What should the argument to dict() be? A list of (key, value) pairs, a list of alternating keys and values, or something else?
As function, I'd say: take either a sequence of tuples or another dictionary as argument. mxTools already has such a function, BTW. -- Marc-Andre Lemburg CEO eGenix.com Software GmbH ______________________________________________________________________ Company & Consulting: http://www.egenix.com/ Python Software: http://www.lemburg.com/python/

Looks like I'm alone with my uncertain feeling about this move... oh well. BTW, we should consider having more than one contructor for an object rather than trying to stuff all possible options and parameters into one overloaded super-constructor. I've done this in many of my mx extensions and have so far had great success with it (better programming error detection, better docs, more intuitive interfaces, etc.). In that sense, more than one way to do something will actually help clarify what the programmer really wanted. Just a thought... -- Marc-Andre Lemburg CEO eGenix.com Software GmbH ______________________________________________________________________ Company & Consulting: http://www.egenix.com/ Python Software: http://www.lemburg.com/python/

Well, I don't see how someone could be doing introspection on int and be confused when it's not a function -- either you (think you) know it's a function, so you use it as a function without introspecting it, and that continues to work; or you're open to all possibilities, and then you'll introspect it, and then you'll discover what it is.
Yes, but the other ways are spelled as factory functions. Maybe, *maybe* the other factory functions could be class-methods, but don't hold your hopes high. --Guido van Rossum (home page: http://www.python.org/~guido/)

Guido van Rossum wrote:
Ok, let's put it in another way: The point is that your are changing the type of very basic building parts in Python and that is likely to cause failure in places which will most likely be hard to find to fix. Becides we don't really gain anything from replacing builtin functions with classes (to the contrary: we lose some, since we can no longer use the function call optimizations for builtins and have to go through all the generic call mechanism code instead). Also, have you considered the effects this has on restricted execution mode ? What will happen if someone replaces the builtins with special versions which hide some security relevant objects, e.g. open() is a prominent candidate for this. Why not put the type objects into a separate module instead of reusing the builtins ?
No... why make things complicated when simple functions work just fine as factories. Multilpe constructors on a class would make subclassing a pain... -- Marc-Andre Lemburg CEO eGenix.com Software GmbH ______________________________________________________________________ Company & Consulting: http://www.egenix.com/ Python Software: http://www.lemburg.com/python/

Adding the atomic types of python as classes I'm +1 on. Perfomance is a problem for the parser to handle. If you have not already done so I suggest that you look at what MicroSoft .NET is doing in this area. In .NET, for example, int is a class and they have the technology to define the interface to an int and optimize the performace of the none derived cases. Barry

Actually, that is not completely true. There is a "value type" and a class version. The value type is just the bits. The VM has instructions that work in the value type. As far as I am aware, you can not use a derived class with these instructions. They also have the concept of "sealed" meaning they can not be subclassed. Last time I looked, strings were an example of sealed classes. Mark.

"GvR" == Guido van Rossum <guido@digicool.com> writes:
GvR> Now invoke the Zen of Python: "There should be one-- and GvR> preferably only one --obvious way to do it." So why not make GvR> these built-in functions *be* the corresponding types? Then GvR> instead of >> int GvR> <built-in function int> GvR> you would see >> int GvR> <type 'int'> +1 GvR> but otherwise the behavior would be identical. (Note that I GvR> don't require that a factory function returns a *new* object GvR> each time.) GvR> If we did this for all built-in types, we'd have to add maybe GvR> a dozen new built-in names -- I think that's no big deal and GvR> actually helps naming types. The types module, with its GvR> awkward names and usage, can be deprecated. I'm a little concerned about this, since the names that would be added are probably in common use as variable and/or argument names. I.e. At one point `list' was a very common identifier in Mailman, and I'm sure `dict' is used quite often still. I guess this would be okay as long as working code doesn't break because of it. OTOH, I've had fewer needs for a dict builtin (though not non-zero), and easily zero needs for traceback objects, code objects, etc. GvR> There are details to be worked out, e.g. GvR> - Do we really want to have built-in names for code objects, GvR> traceback objects, and other figments of Python's internal GvR> workings? I'd say no. However, we could probably C-ify the types module, a la, the exceptions module, and that would be the logical place to put the type factories. GvR> - What should the argument to dict() be? A list of (key, GvR> value) pairs, a list of alternating keys and values, or GvR> something else? You definitely want to at least accept a sequence of key/value 2-tuples, so that d.items() can be retransformed into a dictionary object. -Barry

It would be hard to see how this would break code, since built-ins are searched *after* all variables that the user defines. --Guido van Rossum (home page: http://www.python.org/~guido/)

"GvR" == Guido van Rossum <guido@digicool.com> writes:
>> I'm a little concerned about this, since the names that would >> be added are probably in common use as variable and/or argument >> names. I.e. At one point `list' was a very common identifier >> in Mailman, and I'm sure `dict' is used quite often still. I >> guess this would be okay as long as working code doesn't break >> because of it. GvR> It would be hard to see how this would break code, since GvR> built-ins are searched *after* all variables that the user GvR> defines. Wasn't there talk about issuing warnings for locals shadowing built-ins (or was that globals?). If not, fergitaboutit. If so, that would fall under the category of "breaking". -Barry

You may be thinking of this: >>> def f(int): def g(): int <stdin>:1: SyntaxWarning: local name 'int' in 'f' shadows use of 'int' as global in nested scope 'g' >>> This warns you when you override a built-in or global *and* you use that same name in a nested function. This code will mean something different in 2.2 anyway (g's reference to int will become a reference to f's int because of nested scopes). But this does not cause a warning: >>> def g(): int = 12 >>> Nor does this: >>> int = 12 >>> So we're safe. --Guido van Rossum (home page: http://www.python.org/~guido/)

[Guido]
I think that it will be difficult to avoid creating a new object under jython because calling a type already directly calls the type's java constructor.
Jython already interprets the arguments to the dict type as alternating key/values:
This behaviour isn't documented on the python side so it can be changed. However, it it is necessary to maintain this API on the java side and we have currently no way to prevent the type constructors from being visible and callable from python. Whatever is decided, I hope jython can keep the current semantics of its dict type. regards, finn

On Tue, 5 Jun 2001, Guido van Rossum wrote:
+1
- Do we really want to have built-in names for code objects, traceback objects, and other figments of Python's internal workings?
I would say to put all of the common constructors in __builtin__, and all of the odd ducks can go into the new module.
- What should the argument to dict() be? A list of (key, value) pairs, a list of alternating keys and values, or something else?
A varargs list of (key,value) tuples would probably be most useful. Since most of these functions, before being classed as constructors, were considered coercion function, I wouldn't be against having it try to do something sensible with a variety of args. -- sdm

Is the intent of using int and friends as constructors instead of just coercion functions that I should (eventually) be able to do this: class NonNegativeInt(int): def __init__(self, val): if int(val) < 0: raise ValueError, "Value must be >= 0" int.__init__(self, val) self.a = 47 ... ? Skip

On 05 June 2001, Guido van Rossum said:
+1 from me too.
Cool!
Probably not, as long as they are accessible somewhere. I could live with either a C-ified 'types' module or shoving these into the 'new' module, although I think I prefer the latter slightly.
- What should the argument to dict() be? A list of (key, value) pairs, a list of alternating keys and values, or something else?
I love /F's suggestion dict(k=v, k=v, ...) but that's icing on the cake -- cool feature, looks pretty, etc. (And *finally* Python will have all the syntactic sugar that Perl programmers like to have. ;-) I think the real answer should be dict(k, v, k, v) like Jython. If both can be supported, that would be swell. Greg -- Greg Ward - Linux geek gward@python.net http://starship.python.net/~gward/ Does your DRESSING ROOM have enough ASPARAGUS?

"GW" == Greg Ward <gward@python.net> writes:
GW> I love /F's suggestion GW> dict(k=v, k=v, ...) One problem with this syntax is that the `k's can only be valid Python identifiers, so you'd at least need /some/ other syntax to support construction with arbitrary hashable keys. -Barry

greg wrote:
note that the python interpreter builds that dictionary for you if you use the METH_KEYWORDS flag...
given that Jython already gives a meaning to dict with more than one argument, I suggest: dict(d) # consistency dict(k, v, k, v, ...) # jython compatibility dict(*[k, v, k, v, ...]) # convenience dict(k=v, k=v, ...) # common pydiom and maybe: dict(d.items()) # symmetry
If both can be supported, that would be swell.
how about: if (PyTuple_GET_SIZE(args)) { assert PyDict_GET_SIZE(kw) == 0 if (PyTuple_GET_SIZE(args) == 1) { args = PyTuple_GET_ITEM(args, 0); if (PyDict_Check(args)) dict = args.copy() else if (PySequence_Check(args)) dict = {} for k, v in args: dict[k] = v } else { assert (PySequence_Size(args) & 0) == 0 # maybe dict = {} for i in range(len(args)): dict[args[i]] = args[i+1] } } else { assert PyDict_GET_SIZE(kw) > 0 # probably dict = kw }

On 06 June 2001, Fredrik Lundh said:
Yikes. I still think that #2 is the "essential" spelling. I think Tim was speaking of #1 when he said we don't need another way to spell copy() -- I'm inclined to agree. I think the fact that you can say int(3) or str("foo") are not strong arguments in favour of dict({...}), because of mutability, because of the overhead of dicts, because we already have the copy module, maybe other factors as well.
and maybe:
dict(d.items()) # symmetry
I think this is massive overloading. Two interfaces to a single function ought to be enough. I for one have long wished for syntactic sugar like Perl's => operator, which lets you do this: %band = { geddy => "bass", alex => "guitar", neil => "drums" } ...and keyword arg syntax is really the natural thing here. Being able to say band = dict(geddy="bass", alex="guitar", neil="drums") would be good enough for me. And it's less mysterious than Perl's =>, which is just a magic comma that forces its LHS to be interpreted as a string. Weird. Greg -- Greg Ward - Linux geek gward@python.net http://starship.python.net/~gward/ If you and a friend are being chased by a lion, it is not necessary to outrun the lion. It is only necessary to outrun your friend.
participants (14)
-
aahz@rahul.net
-
Barry Scott
-
barry@digicool.com
-
bckfnn@worldonline.dk
-
Donald Beaudry
-
Fred L. Drake, Jr.
-
Fredrik Lundh
-
Greg Ward
-
Guido van Rossum
-
Ka-Ping Yee
-
M.-A. Lemburg
-
Mark Hammond
-
Skip Montanaro
-
Steven D. Majewski