assignment expression peeve

Carl Banks imbosol at aerojockey.invalid
Mon Oct 20 13:27:15 EDT 2003


Alex Martelli wrote:
> Carl Banks wrote:
>   ...
>> Second, although I was in error to claim it was semantically
>> different, the same is not true of syntax.  Imperative and declarative
>> are different syntaxes: similar, parallel, but different.  This must
> 
> Take Italian (or is it "not a natural language", or do you deem it
> "too alien"?!).  "Prendi il treno": it's impossible to say from this
> sentence whether I'm instructing / pleading / advising ("take the
> train" in English) or simply describing ("you take the train" in
> English).
> 
> Come to think of it, "you take the train" in English can quite well
> be imperative -- "you take the train, I will fly", the boss said to
> the lowly employee; so "you take the train" by itself could quite
> well be imperative, depending on the context and the pragmatics, just
> as well as declarative.  So could (as a parenthetical) be just "take
> the train", as soon as it's in a linguistic environment where it IS
> permissible to drop the pronoun (as Italian lets you do almost always,
> English and French more rarely):
> "Many people each day drive their cars, take the train, or walk to work".
> Yes, sure, you're assumed to implicitly mentally repeat the "many people"
> subject just before the "take the train", but it need not be spelled
> out.  Or, consider "you will hire Mr Smith" -- imperative or descriptive?
> Impossible to tell without context and pragmatics -- syntactically
> undistinguishable (some might still take the will/shall distinction
> as paradigmatic here, but is that still living English...?)
> 
> The boundaries of imperative and declarative are FAR thinner -- particularly
> in real natural languages, as opposed to the half-baked theorizations
> thereupon concocted by theorists in the last few millennia -- than you
> claim.  Much more depends on context and pragmatics than on syntax, in
> REAL natural-language use even more, but in "theoretical" grammar too.


I believe context serves to disambiguate the two moods.  A person
hearing "You go to the train" will know, from context, whether it was
intended as a declarative or imperative, and will react differently
depending on which it is.  (BTW, since go is an immediate action, a
sentence like "you go to the train" is not a common declarative
sentence in English; it would be "you are going to the train".)

What about Spanish, or Latin, where imperatives are grammatically
distinct from declaratives?


>> be reflected, I say, in the analogous phrasing.
>> 
>> 
>>>  "Assignment" to a name *means this*,
>>> in either declarative or imperative moods as you prefer, in
>>> reference-semantics languages such as Python.
>>> 
>>> And what about "the total of this column, which you must also copy
>>> at the start of the Liabilities column for further computation which
>>> we'll explain later, must be underlined with a thick red pen".  This
>>> is copy semantics (quite explicitly) and even an "indexing" -- yet,
>>> while you may not find this the clearest way to explain this specific
>>> tidbit of book-keeping, you can hardly deny it's natural language.
>>> 
>>> underline_with(pen(red, thick), Liabilities[0] := sum(thiscolumn))
>>> 
>>> is the rough equivalent, assuming := as Rubin did to mean "assignment
>>> within expression"
>> 
>> I wouldn't call it a rough equivalent.  In fact, I'd say the text you
>> gave doesn't even have an equivalent--since it's not an exact verbal
>> description of any code.  As I said, that it what I think needs to be
>> for it to be considered analogous (for the purposes of my contention).
> 
> I consider your (attempt at) redefinition of the word "analogue" quite
> Humpty-Dumpty-ish, inappropriate, and unusable for the purpose of
> reaching any practical conclusion.

I did not redefine analogue; I merely wondered if it was the wrong
word for what I was thinking about.

I've been trying to explain why I think what I was called an analogue
is the only appropriate thing to use in this case.  Could you explain
why you think it's not?



[snip]
> So, if I choose to read, e.g., the code (with the usual hypothetical
> := to denote assignment-in-expression, a la Rubin):
> 
> kill( john := guy('tall', 'blond', 'near window') )
> 
> as
> 
> "Kill John, the guy who's tall and blond, there near the window"
> 
> I claim I have the strictest "analogue" anybody can wish between a
> programming language notation and a natural language sentence, even
> though in the latter I've had to use different punctuation and insert
> fillers such as "the", "who's", "and", "there".

I no longer care about your (or American Heritage's) particular
definition of analogue.  You want to claim it's an analogue, fine with
me.

All I care about is whether a reader will see the given line of code
and will parse it in his head using the same syntactical structures as
the sentence you worded it as.  I do not care whether the sentence
meets your definition of analogue.

The sentence you gave above not only isn't how a programmer would
parse the line of code, but it also falls back into the mistake Rubin
made: it doesn't communicate that anything is being reassigned (which,
you might remember, you AGREED with).

A programmer might very well summarize the line that way, but that
would be the result of taking it apart and reconstructing it, and not
caring to retain the exact syntax (or meaning, in this case).  When
the programmer READS it, those aren't the words that are entering his
head.


> The reading of the
> subexpression
>    <name> := <identification>
> as "<name>, <identification>" is perfectly natural in context -- few
> translations from computer to natural language can POSSIBLY be more
> spontaneous and obvious than this, an "assigment expression".

Can you give me an example that doesn't fail to communicate that
something is being assigned?


> So, ANY part of your case against assignment expressions that rests
> on "lack of analogue in natural language" is entirely bogus, and indeed
> totally counter-productive, as I'm pretty sure I'm not the only one
> who, starting out with diffidence against assignment expressions, is
> gradually coming to find them more and more acceptable, just because
> of the need to argue against this totally bogus contention and the
> wealth of absolutely obvious counterexamples that totally demolish it.

I think your counterexamples don't demolish it because very few of
them reflect how the reader parses the code.

A programmer never sees "guy = bob" and reads it as "a guy named bob";
the programmer parses it as "assign guy to bob" and later, through
flowery cerebrations, might turn it into "a guy named bob".  But WHILE
reading it?  No.

I don't care one bit whether it's analogous, or whether it has
equivalent semantics, or whether it's syntactically parallel.  I don't
care.  It *has* to reflect how the reader parses it, and almost none
of the examples you gave do that.


Having said all of that, your examples used parentheticals and
relative clauses as analogues, which are two possible other ways to do
assignment expressions.  Although the wording precluded those examples
from being verbal equivalents, the strategies are legitimate.  Of
course, whether they can be verbal equivalents depends on the
programmer.


>>> MOST definitely, nothing ANYWHERE as deep that you can justify your
>>> exaggerated claims about "assignment expressions" being so utterly
>>> foreign to natural language!!!
>> 
>> It's not so much that it can't be done, so much as it is that it won't
>> be done.
>> 
>> Sure, your examples are very close semantically and syntactially--but
>> when a human reader sees such code, will they think that way?  In
>> other words, faced with an embedded assignment expression, will the
>> reader deftly change what they normally think of as an imperative to a
>> declarative on the fly, so that it works syntactially while
>> maintaining the semantics?
> 
> To reiterate: you're making a mountain out of the molehill of the
> distinction between imperative and declarative, trying to shore up
> a crumbly contention that most definitely doesn't deserve to be --
> doesn't deserve anything else than to die a shameful death.
> 
> When the ordinary person reads
>    print max(amounts)
> they read "print the maximum of the amounts";

Right.


 they don't have ANY
> problem switching from imperative "print" to descriptive "the
> maximum of", nor need they make any attempt to turn this around
> to "compute the maximum of the amounts and then print it" in order
> to ``maintain'' your cherished ``imperative'' throughout.

max(amounts) is an expression.  The verbal eqivalent of an expression
is a noun phrase.  "The maximum of amounts" is a noun phrase.  It is,
by my definition, a correct analogue.  Probably the first example you
gave that I approve of.

Of couse, some functions have side effects and don't return a useful
value.  Most programmers would think of those as commands, so commands
are appropriate there.

Notice that there's no "precious imperative" here.  My only concern is
how the programmer thinks of something.  If the programmer looks at a
function and thinks imperative, then the verbal equivalent must be an
imperative (not a declarative).  If the programmer thinks noun phrase,
then the equivalent must be a noun phrase.  And if a programmer looks
at an assignment and sees imperative, then the verbal equivalent must
be imperative.


> So, any claim that "kiss cinderella, the fairest of them all"
> is not an "analogue" to
>    kiss( cinderella := fairest(themall) )
> _just doesn't wash_.

Again, you've slipped into the same mistake Rubin made.  It doen't
communicate that something is being reassigned.  Not only does it not
wash, but it's something you previously agreed does not wash.


>  The "mood switch" imperative -> declarative
> is far easier than you suppose and already needed to read the plain
>    kiss( fairest(themall) )
> as "kiss the fairest of them all" rather than "compute/determine the
> fairest of them all and then kiss her/him/it" which would be rather
> periphrastic AND require the introduction of a pronoun which just
> isn't there in computer languages [except in Perl, if you coded
>    &fairest(@themall) and kiss $_
> I suppose:-)].

That was not a switch from imperative to declarative.  "The fairest of
them all" in a phrase.  It is neither imperative or declarative: only
a clause or a complete sentence can be declarative or imperative.  So,
using "Kiss the fairest of them all" is NOT switching to the
declarative.  It is using an expression as a noun phrase, as a good
verbal equivalent should.

The "imperative" version you gave is not a verbal equivalent, of
course, because no programmer would parse it that way.


> The "assignment expression" is a perfectly natural parenthetical
> which adds no difficulty at all.  There are MANY other constructs
> in Python which would present FAR worse difficulties if one were
> to accept that laughable idea of "analogue" which you presented,
> yet give no difficulty whatsoever in practical use.

That's possible, although there's not many.  The one you'll go on to
mention does, in fact, cause a little confusion.  But we'll get to
that.


>> Perhaps the flowery among us can do that easily enough; perhaps you
>> can.  In that case, I have no objection to your counterexamples
>> (except to point out that a flowery person will still have to learn
>> when to adjust his thinking).
>> 
>> Personally, I don't.  I think I usually parse embedded assignments
>> using some sort of recapitualtion, like this:
>> 
>>     "if [let] a equal b, that quality, is equal to zero..."
>> 
>> That recapitulation, of course, produces a hiccup in my reading,
>> requiring more effort.  I can read the following a lot easier:
>> 
>>     "[let] a equal b.  If a is equal to zero..."
> 
> If "a=b" is to be read "let a equal b", then how can you possibly
> manage to contort your brain around such Pythonisms as
>    foo(bar=23, baz=45)
> ???

Well, I've never been trying to claim I can't warp my brain around it.
Whether, and how easily, I can wrap my language circuits around it is
a different question.

I would parse the above as "foo, with bar equal to 23, baz equal to
45."  This is going to sound silly, but I'm serious: because there's
no assignment there, you don't have to communicate that anything is
being assigned, so you don't need an imperative (or declarative).

I claim it's easier to "adjust one's thinking on the fly" here because
function calls do this all the time, and we expect these
pseudo-assignments when we see a function call.  Assignment
expressions, being expressions, can appear anywhere an expression
appears.


Incidentally, default arguments in a function definition is a lot
worse--a lot of people do take them as assignments, and are surprised
when their code doesn't work as expected.  I definitely think a
different syntax would be an improvement there.


>  Using sensible 'transliterations', you'd read "if (a:=b+c)==0:" as:
>    if a, which is b+c, equals zero, ...

Again, failure to comminucate something is being assigned.  "a, which
is b+c" says what is, not what's happening at the moment.  a, which
becomes b+c" would work, and would be a verbal equivalent, IF that's
the syntax the programmer uses when reading it.

As I've said, as long as this is what happens, I have no objection to
this example.  In fact, the idiom is probably common enough in C that
most programmers come expect it after an if, and can learn to adjust
their thinking on the fly so they can read this function without
hiccuping.

Outside of this idiom, the assignment expression is unexpected, and
the reader probably won't adjust, and has to resort to something like
recapitulation to parse it.


> and that call to foo as something like
>    [call] foo, naming as 'bar' 23, [and] naming as 'baz' 45

Good.  (clap, clap, clap)


> If you can't read "a=b" as anything but "let a equal b" you have a
> lot of problems finding "analogues" to many other Python constructs
> already --

Again, it's not "can you", it's "will you".  Say you're scanning
quickly through C code.  You're moving along nice and quickly, taking
in the gist quite well, and then BAM! you get tripped up.  You have to
go back and reread something.  Why?  An assigment expression confused
your language circuits.  You more carefully read the guilty line, and
obtain the correct meaning.


> and if you insist in reading the hypothetical new
> "naming" operator := in just the same way as you read "=", well,
> then the problem is clearly with your flexibility in finding sensible
> transliterations.  Having taught many newbies, I can assure you that
> this is the least of their problems.

The new opererator would help, I think, but not eliminate the tendency
to think of := as an imperative.


>>> and playing just the same rome anyway).  "Make sure the discounted
>>> net present value, call it NPV for short, looks very appetizing, to
>>> avoid the suits laughing in your face, since it's by NPV alone you
>>> will set their minds in motion".
>> [snip rest-no I'm not stuck on word order]
>> 
>> Again, not an exact verbal description.  These sort of embedded
>> commands have an idiomatic air to them (to me, at least), and don't
> 
> Being idiomatic _IS_ typical of well-used natural language!  So
> how can you possibly claim assignment expressions "have no natural
> language analogue"?!?!?!

What I meant was, nesting a parenthetical command like "call it"
sounds all right because we're familiar with it; generally, such a
command would be a bit awkward.  It's a minor point, though.  You may
take it as a concession.


>> sound quite as good in an exact verbal description.  I also think the
> 
> It doesn't sound FORMAL, not in the context I put it in, of course.
> I can just as easily find a perfectly formal-sounding context:
> 
> "Ensure that your posts' bogosity, which is verbosity times pomposity
> divided by gist, is below the laughability threshold, defined as 74.6,
> to avoid excessive derision.  If the bogosity exceeds twice the laughability
> threshold, run for your life".
> 
> There -- formal enough for you?

I don't care if it sounds formal.  I was saying that if you tried to
use a verbal equivalent (i.e., not merely an "analogue"), then the
parethetical command doesn't sound so good.

"observe a, set it to b" is ambiguous about when a is being set, and
so I doubt a programmer would parse it that way, meaning that it is
not a verbal equivalent.



[snip] 
>> parenthetical nature of it communicates the idea that it could have
>> been uttered anytime; yet in the case of assignment expressions,
>> that's not true.
> 
> The parenthetical does indicate that the sentence COULD have been
> broken.  "One day John, who was a just and fair King, went to chase
> bears in the woods", versus
>  1. John was a just and fair King
>  2. One day John went to chase bears in the woods
> and similarly: "Ensure that bogosity, defined as XYZ, is below Z"
> could be rephrased:
>  1. Bogosity is defined as XYZ
>  2. Ensure that bogosity is below Z
> and _IN STRICT ANALOGUE_ for assignment expressions,

Once again, it does not communicate anything is being assigned.  It is
not a strict analogue.  Once again, you have previously agreed with
that.

In this case, it makes a difference.  When you communicate that
something is happening, rather than that something is, it matters WHEN
it happens.  The parenthetical command is often ambiguous about that.

Because of that, I don't believe programmers will usually think of an
embedded assignment as a parenthetical command, meaning that it is not
a verbal equivalent.


> you can write
>  ensure( (bogosity:=verbosity*pomposity/gist) < laughability )
> OR quite equivalently
>  bogosity = verbosity*pomposity/gist
>  ensure( bogosity < laughability )
> 
> The parallels are SO strict it's mind-boggling to see them denied.

Except that it fails to communicate the assignment.


> Even your cherished "imperative mood" is easily maintained throughout
> if one makes a fetish of it:
>  "Ensure that bogosity (compute it as ...) is below laughability"
> 
> And YES, there are PLENTY of passages like this, in the yearly
> instructions on how to compute one's sundry taxes, that the average
> Italian citizen has to contend with.  And I've seen plenty like that
> in all other natural languages I know, too.
> 
> Of course being able to NEST can be abused -- the Zen of Python's
> "flat is better than nested" DOES matter.  But just as you can NEST,
> e.g.,
>   foo(bar=baz+fie)
> so would the potential for clarity remain with assignment expressions,
> side by side with the potential for obfuscation.  Anyway, the point
> in your argument that I find completely unacceptable is the "no natural
> language analogue" part -- natural language has the potential for
> obfuscation FAR more than computer languages to, partly because the
> PURPOSE of NL utterances IS sometimes to obfuscate and befuddle rather
> than to clarify, after all.

My problem with this is that that the obfuscation of natural language
doesn't come from syntax.  Syntax is quite strict and regular in
language, although more intricate than programming syntax, of course.


>> How would "observe(a:=b)" be done using parentheticals, while keeping
>> it to be an exact verbal descrption?
> 
> "observe a, which is b".

Two things:

1. I don't want to sound like a broken record, but this is once again
   the same mistake Rubin made.

2. I meant parenthetical command.  We've already discussed relative
   clauses.  How would you do that as a parenthetical command?


>>> Etc, etc.  It seems truly ridiculous to see you trying to deny
>>> the close analogies between all of these usages and "assignment
>>> expressions" with irrelevant quibbles on declarative vs imperative
>>> and the like.
>> 
>> Sorry, hopefully I've stated my reasons for this more clearly.  The
>> analogies have to be very close analogies, i.e., exact verbal
>> descriptions, because they're supposed to reflect how a person parses
>> the code.
> 
> I suspect they're supposed to reflect how YOU parse the code WITH
> all your allegedly-etched-in-stone prejudices such as "set a to b"
> as the only natural transliteration of "a=b" (which would also make
> OTHER Python constructs quite a mess to read).

I'm sure my opinions are colored by how I parse code.  Perhaps I'm
just lingustically obtuse.  Or, maybe other people share some degree
of this "obtuseness" with me.  My money's on the latter.


>>>> What about assignment expression?  If you think of the programming
>>>> language as imperative, "a=b" would parse as "Set a to the value of
>>>> b."  If declarative, "a=b" would parse as "a gets the value of b."
>>> 
>>> Nope!  "use a as the name for b", "a, which is the name you must
>>> use for b,", "a, and remember to use that name for b," etc, etc.
>>> That's in reference-semantics language such as Python.  If you're
>>> keen on word order, "speed, which is distance divided by time, you
>>> must keep under 50 MPH on this road to avoid a fine" -- half
>>> imperative, half declarative / explanatory, it doesn't matter --
>>> the term being assigned-to (defined) at the start, then the
>>> assignment (definition of the term), then the imperative.
>>> 
>>> Come on, you just can't SENSIBLY keep denying this is natural
>>> language!
>> 
>> No, right now I'm denying that these are analogous.
> 
> I hope this is a last-ditch defense of a contention into which you've
> invested far too much energy and emotion to easily admit it's untenable.

Last ditch?  Come on, that was the theme of my whole post!


> "if distance divided by time, call it speed, is above 50 MPH, decelerate"
> 
> and, since you HAVE claimed you're not stuck on word-order
> 
> "if (speed := distance/time) > 50: decelerate()"
> 
> how CAN you claim these are ANYTHING *BUT* ANALOGOUS?!

I don't!!!  But if the programmer doesn't see "speed := ..." as "call
it speed", then it's not a verbal equivalent, and not being one, it
will be more difficult to read, or at least harder to learn.  Even
though it's completely analogous.


>>> Yeah, right, "QED".  You just cannot speak of "the blond guy
>>> (remember to call him Bob!)", etc, wherever you could speak
>>> of "the blond guy", right?  "Fiddlesticks" is putting it mildly.
>> 
>> You've misunderstood me here, I think.
>> 
>> Take the following two pseudo-code lines:
>> 
>>     a = b
>>     if a == 0
>> 
>> Here are their Engligh exact verbal descriptions (remember, I don't
>> care about assignment semantics):
>> 
>>     set a to b
>>     if a is equal to 0
>> 
>> Now, if a=b is an expression, you could substitute a=b for a, like so:
>> 
>>     if (a=b) == 0
>> 
>> What I'm saying is, if assignment is an expression, then, like every
>> other expression, it should work as a drop-in replacement in its
>> natural language analogue (read: exact verbal description).  However,
>> it does not:
>> 
>>     if set a to b is equal to 0
>> 
>> The only way to make this grammatically correct is to reword the
>> assigment, and when you do that, it's no longer a drop-in replacement.
> 
> Say that, as Rubin wished, we use := rather than = for assignment
> when it's in an expression.  Then, any claim that "a=b" and "a:=b"
> should or would be read the same way is OBVIOUSLY false.

It's not obvious to me.  The mere fact that it has a side effect tends
to bring the imperative interpretation (or on-the-fly adjustment to
something else).

I've been saying assignment is seen by the programmer as a command,
even if it happens to be an expression.  I say the same would happen
with :=, and the fact that there would be an assignment statement
doesn't change that.

It might help, especially if := is never used alone in a statement.
But the tendency to read things that have side effects as a verb is
still there.


> You can
> always read "a:=b" as "a, which is b,"  since it cannot occur by
> itself (yes, Python generally accepts free-standing expressions, but
> it's easy to make it NOT accept the hypothetical "a:=b", should we
> add it, as stand-alone).

You can, but I don't think anyone will.  

(Would it be easy to make Python not accept (a:=b) freestanding?)


>> Well, sorry.  Obviously, if one has a very loose definition of
>> analogy, one can make language do just about anything.  The problem
> 
> I accept the dictionary definitions, say American Heritage, both
> the "normal everyday language one":
> 
> 1a. Similarity in some respects between things that are otherwise
> dissimilar. b. A comparison based on such similarity. See synonyms at
> likeness.
> 
> and the specialistic one in Linguistics, as we're talking about languages:
> 
> 4. Linguistics The process by which words or morphemes are re-formed or
> created on the model of existing grammatical patterns in a language, often
> leading to greater regularity in paradigms, as evidenced by helped
> replacing holp and holpen as the past tense and past participle of help on
> the model of verbs such as yelp, yelped, yelped.

Definition 4 doesn't apply to this case.

Definition 1 is open--it doesn't say what those respects are.  I
wonder if it's legal to say what those respects are and disqualify
something as an analogue because of it.  If not, then forget I ever
said analogue.


>> is, these loose definitions don't really mean much when trying to
>> compare them to code readability.
>> 
>> You disagreed with my contention; and frankly, with your idea of what
>> a natural language analogy is, I don't blame you.  Understanding
>> better my idea of what it is, does my contention make more sense?
> 
> Sorry, but [a] "my idea" is, essentially, the American Heritage's
> Dictionary's, and [b] I don't think it makes any sense to use your
> newfangled humpty-dumptyish redefinition of "analogy", because if
> you try to apply it just as strictly to all existing Python constructs
> it repeatedly falls to pieces.

There are some it works better than others for, of course.  I don't
think it repeatedly falls to pieces; the vast majority of Python code
passes the verbal equivalent test.


> I think you're trying to argue for "I want to read 'a:=b' EXACTLY LIKE
> the different construct 'a=b', and THEREFORE ..." and I don't see
> that it makes any sense to express this as "analogy to natural language"
> or lack thereof -- particularly when the construct "a=b" is already
> best read in very different ways, depending on context, in the
> language as it stands!

I don't say a:=b would be read exactly like a=b, but they will both
have the tendency to be read the same.  It's a question of how things
could be read, but how they are read.


> I hope I can drop out of this thread now, hopefully BEFORE I become
> the keenest paladin in the world for assignment-expressions due to
> having to defend them against totally absurd charges!-)

Just keep in mind that I've decided that I really don't like
assignment expressions for a different reason (not that the difficulty
of a verbal equivalent still isn't a small contributing factor).
Other things that fail the verbal equivalent test don't bother me
nearly as much because they don't have the ugliness problems.

But if you're done, it's been an interesting discussion.


-- 
CARL BANKS                   http://www.aerojockey.com/software

As the newest Lady Turnpot descended into the kitchen wrapped only in
her celery-green dressing gown, her creamy bosom rising and falling
like a temperamental souffle, her tart mouth pursed in distaste, the
sous-chef whispered to the scullery boy, "I don't know what to make of
her." 
          --Laurel Fortuner, Montendre, France 
            1992 Bulwer-Lytton Fiction Contest Winner




More information about the Python-list mailing list