New language

Martijn Faassen m.faassen at vet.uu.nl
Tue May 29 16:30:34 EDT 2001


In comp.object Topmind <topmind at technologist.com> wrote:
>> Topmind <topmind at technologist.com> wrote:
>> 
>> >> Topmind <topmind at technologist.com> wrote:
>> >> [snip]
>> >> > Python blew an opportunity for minimalism. They could have made
>> >> > touples, dictionaries, and classes all the same thing, for example. The 
>> >> > differecence are not large enough to justify 3 seperate syntactical
>> >> > creatures, and the difference could have been mitigated.
>> >> 
>> >> Topmind: in Python, instances are syntactic sugar for dictionaries.
>> 
>> > Is that new? My Oreilly Programming Python
>> > version 1 says they are different
>> > on page 239.
>> 
>> As far as I know it's always been like that.

> Well, there appears to be a discrepency somewhere.
> Perhaps one can use a dictionary to *access* methods,
> but that is not the same as methods *being* 
> a dictionary.

Methods aren't a dictionary; *instances* are. An instance of a
class is mostly a dictionary of its attributes.

a.foo = 1

is equivalent to:
 
b['foo'] = 1

where a is an instance an b a dictionary.

An instance has a little bit more to refer to its class(es) of course, 
but classes themselves are implemented by using dictionaries as well.
Just try .__dict__ sometime on things in Python and see the dictionaries
everywhere.

[snip]
>> > What do you mean by "heavy-weight"?
>> 
>> More work typing and handling them in your code, under certain circumstances
>> such as the return value case I just gave. 

> Which I disagreed was a noticable improvement over "traditional"
> parameter passing and dictionaries. More on that below.

I disagree that it's not a noticable improvement; I wrote why in
my last post. I'm curious what you'll have to say about that, so
I'll read on. :)

>> Another good example is for
>> instance x, y coordinates you want to pass around, without going to the
>> trouble of  dealing with anything more complicated.

> What keeps a dictionary from satisfying this role?

They're too heavy, again. :)

>> I think tuples may also take less memory and processing time when used
>> this way, but that's relatively unimportant. The case you could make 
>> against them could include the argument that you could provide syntactic
>> sugar that allows you to do something similar with dictionaries/objects.

> I think that was my case, more or less. Touples, dictionaries, and
> classes have too much *overlap* in Python. It just seems to me that
> they could have factored the 3 into *one* thing. It keeps the
> language cleaner and the learning curve shorter that way.

I disagree; I think a distinction like this can help sometimes. Look at
Perl and their scalars, which merges things like integers, floats and
strings into 'one thing'. They also seem to merge lists and dictionaries
(hashes) into one thing. I think that's bad; you want your programming
language to complain if you're treating something as an integer when
it's really a string (can't add "one" and "two").

It's funny you should compare tuples with dictionaries and say they 
should be conflated; most people complaining about tuples say they're
too much like *lists* (arrays). They're right that they're very much
like lists, except that they're immutable (like integers and strings
in Python, but unlike lists and dictionaries and instances). Your
desire to conflate them with dictionaries is in my opinion wrong as well,
but you're more right than those who want to merge them with lists; 
tuples are generally used as 'records' (heterogenous objects) and not
as lists of homogenous objects.

Anyway, you're in the LISP and Smalltalk camp here; do a lot with just 
a few syntactic (surface semantic) concepts. A language like Python
adds more syntactic sugar, and my theory is that this syntactic 
sugar *helps* programmers write and read programs. Too much syntactic
sugar can result in messes (Perl is another good example here), but
too little also has some disadvantages. People are sometimes a bit too
focused on the conceptual purity and the ability to manipulate program
code; in a pragmatic language the tradeoffs may sometimes favor more
syntactic sugar, not less.

> For example, do have OO,
> allow dots to be represent dictionary items:

> a["foo"] = 3

> a.foo = 3

> (Both are probably needed in case spaces are used in the key.)

> Have a special option indicator for a "parent" dictionary,
> and wallah! you have inheritance:

> a.__parent__ = bar

> or perhaps

> a.__parent__ = "bar"      # the "by name" approach

You've just reconstructed Python, besides some minor details and
a little bit of missing syntactic sugar (easy and clear way to 
construct the parent dictionary AKA the class):

class A:
    # add an attribute to the parent dictionary
    b = 2
    
    # we can also add method attributes to the parent dictionary
    def bar(self):
        return "Bar!"

    # a special method that helps us with construction of 'children'
    # (instances) of this parent dictionary
    def __init__(self):
        self.foo = 3

# okay, make a 'child dictionary'; the instance of the class
a = A() # uses __init__

# let's add something to the 'child dictionary' (instance)
a.something = "hi"

print a.b
print a.bar()
print a.something

# note that while 'b' and 'bar()' are defined on all child dictionaries,
# 'something' is only defined on the 'a' dictionary.

# let's show the internals:

# the contents of the child dictionary (AKA the instance)
print a.__dict__
# the parent dictionary (AKA class) this child dictionary has
print a.__class__ 
# the contents of the parent dictionary
print A.__dict__

The output:

2
Bar!
hi
{'foo': 3, 'something': 'hi'}
__main__.A
{'__init__': <function __init__ at 8068e68>, '__doc__': None, 'bar': <function bar at 8068e48>, 'b': 2, '__module__': '__main__'}

>> > Besides, what is wrong
>> > with regular by-reference parameters? 
>> 
>> Nothing at all, except that returning multiple values is far more clear
>> by just about any measure you can come up with. :)

> Which would be?

> I suppose you could argue that under the old approach
> one could not tell what was being changed and what was
> not by looking at the caller. However, you might have to check
> the bottom or middle instead of the top of a routine to
> figure out the result parameter interface in Python.

Usually the bottom, yes, unless you document it at the top in 
a docstring. Looking for 'return' statements isn't terribly
difficult, either.

> IOW, it might trade caller readability for callee
> readability. At the most it is a wash IMO.

I disagree; caller readability is not significantly effected and
callee readability (in multiple places) is improved. A clear win,
therefore.

> Having the entire interface defined at the top is
> a good thing IMO. (Although "return" is rarely
> at the top, but it is a single item if it
> exists.)

A single item of any kind of complexity, anyway, and a serious tradeoff
in readability for the callee as there are now two different ways you can
return values, one of which (reference parameters) is a hack.   

>> > I see no reason to deviate from tradition unless it 
>> > does something better. It is a "cute" idea, but I
>> > don't see any advantage to by-ref parameters.
>> 
>> It's a very old tradition in many programming languages that functions get
>> their input through their parameters, and return their output with
>> a return statement. It's a bit strange that as soon as you have to
>> return multiple things, you'll have to go deal with these odd by reference
>> parameters (output through input? not syntactically obvious when you're 
>> calling such a function? great idea!) or alternatively have to create a lot
>> of syntax just to return a datastructure of two elements (as you'd need to do
>> in C, for instance).

> C is hardly the pennacle of programming languages. Using that
> as the alternative to Python is misleading. 

Well, I could constrast Python with Python, where the tuple syntax is 
minimal and you can return a number of items easily (and get at the
again). But I couldn't do that, as I was already talking about Python. :)

> If you want to return 2 elements, then use a dictionary.

Let's compare:

def foo():
   return {'x': 1, 'y': 2}

dict = foo()
x = dict['x']
y = dict['y']

versus

def foo():
   return x, y 

x, y = foo()

Come *on*, man! Harder at the callee *and* caller side, even in a language
that constructs dictionaries as easily as Python.

>> Anyway, Python's ability is just a consequence of the ability to return a
>> tuple in Python, like this:
>> 
>> def foo():
>>    return "my", "tuple"
>> 
>> t = foo() # t now contains a tuple.
>> 
>> and the ability to 'unpack' tuples, like this:
>> 
>> a, b = t
>> 
>> They both seem to be entirely reasonable constructs, the combination
>> is entirely reasonable too and in fact a lot clearer when you're reading
>> code than by reference parameters, so why object against them out of
>> some idea of tradition?

> Because I am not convinced it is significantly better. As a rule of
> thumb, I say something has to be at least 15 to 30 percent better to
> deviate from tradition. Perhaps if I saw more actual uses for 
> it besides foo-bar examples, but I have not.

'15 to 30 percent better': failure to grok error. If you mean the amount
of typing, I can see it's far more than 30 percent better. But you
probably don't mean that, and it's fairly meaningless beyond that.

> Most "data structures" I deal with are more than 2 positions.
> Thus, I use tables, and perhaps a dictionary-like thing to
> interface to such records. (I prefer to use tables to store
> data instead of dictionaries themselves, other than an interface
> mechanism to specific records.) Perhaps some niches have lots of
> "skinney collections" where touples may help, but not mine.

Well, I tried to describe such a niche; returning multiple things from
a function. Another niche is indeed the very light weight record 
niche; x, y coordinates for instance. Yet another niche, harder to
describe is the 'make a new immutable object from other immutable
objects' niche. 

I'm not saying python's tuples are perfect or the only solution, and
they're certainly not good for all purposes, but they seem to have
their niche.

>> If you're objecting against cute because we have an old tradition, you'd
>> object against this consequence of tuples and tuple unpacking too, I'm sure:
>> 
>> a,b = b,a # swap a & b

> Yes, because it is not obvious what is going on. Perhaps if 10+ percent
> of all code was devoted to swapping, then I might agree. As it is,
> swapping is something that is done perhaps 1/1000 lines. At that
> low rate, it is nothing more than an intellectually cute idea
> that can confuse people.

But it *is* obvious what is going on as you already understand both
tuple unpacking and tuple construction. We're just doing both in a
single line. There's nothing special case about this. It's not *hard*
to understand tuple construction and unpacking. You're clinging to
your traditions here just for argument's sake. :)

If this were the *main* reason for having tuples in a language, then of
course I'd agree with you. But this is just a consequence of their
presence.

> My philosophy is optimize the syntax for the *common* stuff. I don't
> see Python doing that, at least not the way I code.

I myself tend to return multiple values from a function frequently,
and passing x,y coordinates around happens somewhat frequently
as well. I have mentioned the ability to use tuples as a dictionary
key before, and I haven't talked about using tuples to catch 
an arbitrary amount of arguments to a function yet, something which 
can be useful sometimes. For me, tuples are an optimisation of
common stuff.  
 
> Don't get me wrong, there are languages a lot worse than Python,
> but the poor consolidation of the similar things I mentioned
> kind of bug me.

I see these syntactic issues in a somewhat different philosophil light,
something which I tried to describe above. While I'm all in favor of
semantic minimalism, I'm not a syntactic minimalist. If you're a
syntactic minimalist these subtle differences make no sense, indeed.

Anyway, if I were designing a new language I would indeed attempt to
bring dictionaries and tuples closer together, so we're in agreement
in that sense as well. I'm just defending the special syntax for tuples, though
I also wonder about performance (but we'd just have to profile it) if
all tuples were dictionaries.

Regards,

Martijn
-- 
History of the 20th Century: WW1, WW2, WW3?
No, WWW -- Could we be going in the right direction?



More information about the Python-list mailing list