binding a reference to a variable

Tim Peters tim.one at comcast.net
Sat Apr 13 03:20:48 EDT 2002


[Andrew Koenig, on spelling SNOBOL4-ish unevaluated expressions]
> Yup.  But why not
>
>         arb = null | (len(1) + indirect(lambda: arg))
>
> ?

[as opposed to creating a class to model "SNOBOL4 variable"]

It depends on all you're trying to do.  At the time, I'm not sure Python
even had a lambda expression; if it did, it certainly didn't have lexical
scoping, so it would have been more like

         arb = null | (len(1) + indirect(lambda arb=arb: arb))

to break dependence on global names -- but that wouldn't have worked without
more tricks, as it requires a binding for arb first in order to establish
the default-argument value.

Now that it's possible to rely on lexical closures, I gotta say I look at

    indirect(lambda: arb)

and shudder a little, especially when plain "arb" *can* serve by playing
(previously sketched) tricks with the spelling of "=" instead.  I'd like the
pattern part to be as easy to read as possible; whatever gimmick attaches a
name to a pattern is dull boilerplate, and I can easily learn not to see it.
This is a dodge the Pythonic mind may be too quick to take, though, as about
once a year it suddenly (re)strikes me how silly the Python idiom

    while 1:
        line = f.readline()
        if not line:
            break

really is <0.9 wink>.  The other 364 days I don't notice the hair.

> ...
> Indeed.  But I want more Snobolish than Iconish patterns.

Me too, most of the time.  The paper introducing Icon argued strongly for
the benefits of integrating SNOBOL4's pattern-matching sublanguage with the
rest of the language, but in practice I stare at an old Icon program and
have a hard time finding "the pattern" part!  Matching and computation are
so seamlessly interleaved it can be hard to change what either part is doing
without screwing the other, or just to see what either part is doing on its
own.

BTW, from the start there was one beyond-SNOBOL4 gimmick I wanted that drove
me to think modeling variables as class instances would be best:  I
mentioned I had a var.ass(pattern, option) method to model conditional and
immediate assignment.  I also had another option:  accumulated immediate
assigment, meaning that all assignments to var during a match attempt were
appended to a list of matches.  So, e.g., given a pattern to match a run of
digits, then

    var.ass(that_pattern, ACCUM) + fail

is a pattern to find all runs of digits (in unanchored mode), and afterwards

    var.matches()

is a list of the matches.  There were some other gimmicks attached to var
instances too, like returning slice indices instead of actual strings (the
engine worked with slice indices under the covers anyway, and it was
sometimes more important in *uses* to know that a match spanned positions
subject[14:17] than that 'foo' was the substring that matched -- and giving
the user a way to know the indices is a lesson we rammed into Python's
regexp facility).






More information about the Python-list mailing list