I'm wrong or Will we fix the ducks limp?

Jussi Piitulainen jussi.piitulainen at helsinki.fi
Tue Jun 7 04:41:11 EDT 2016


Marko Rauhamaa <marko at pacujo.net> writes:

> Gregory Ewing <greg.ewing at canterbury.ac.nz>:
>
>> Marko Rauhamaa wrote:
>>> Seriously, though, it is notable that the high-level programming
>>> languages pretty unanimously refuse to make variables first-class
>>> objects. I wonder why.
>>
>> That's an interesting question. One reason might be
>> that in the absence of static type analysis, assigning
>> to a variable holding a reference to another variable
>> would be ambiguous. For example, suppose Python had
>> an & operator that gives you an object referring to
>> a variable somehow. Then, after
>>
>> a = 42
>> b = 17
>> c = &a
>> c = &b
>>
>> does 'c' now hold a reference to the variable 'b', or
>> does it still hold a reference to 'a' and 'a' now
>> holds a reference to 'b'?
>
> If variables were ordinary mutable objects, you'd need a syntax of
> dereferencing, just like in C. Variable objects would be highly
> analogous to single-element arrays, little boxes if you will.

I've had this little piece lying around ever since there last was a
discussion about assignments as expressions. It abuses the ** operator
to store values in boxes; the value of 'expression ** x' is the value of
'expression', with the side effect that afterwards the value of x.it
(the dereferencing!) is also whatever the value of 'expression' was.

class Box(object):
    '''Read ** as as and x.it as whatever was saved as x.'''
    def __init__(self, init = None):
        self.it = init
    def __rpow__(self, it): # f() ** self
        self.it = it
        return self.it

data = iter('piäsiäntösesti ee näen')
from string import ascii_letters as ascii

x, y = Box(), Box()
while (next(data) ** x in ascii and
       next(data) ** y in ascii):
    print(x.it, y.it)
# Prints one line: p i

There's a further test case in that file, saving the regex match object
during the expression that tests whether there was a match object. Not
entirely satisfactory, but perhaps mildly interesting.

import re
beg = re.compile(r'start=(\w+)')
end = re.compile(r'finis=(\w+)')

b, e = Box(), Box()
for k, line in enumerate(('xxx',
                          '# start=eka rivi',
                          'ween',
                          'ween',
                          '# finis=vika rivi',
                          'xxx')):
    if not b.it and beg.search(line) ** b:
        print(k, b.it.group(1))
    elif b.it and end.search(line) ** e:
        print(k, e.it.group(1))
        break
    elif b.it:
        print(k, line)
# Prints four lines:
# 1 eka 
# 2 ween
# 3 ween
# 4 vika


More information about the Python-list mailing list