By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
434,786 Members | 1,142 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 434,786 IT Pros & Developers. It's quick & easy.

assignment expression peeve

P: n/a
OK, I want to scan a file for lines matching a certain regexp. I'd
like to use an assignment expression, like

for line in file:
if (g := re.match(pat, line)):
croggle(g.group(1))

Since there are no assignment expressions in Python, I have to use a
temp var. That's a little more messy, but bearable:

for line in file:
g = re.match(pat, line)
if g:
croggle(g.group(1))

It gets annoying when there are 4 different regexps that the line
might match, and I want to do something different depending on which
one matches. That's not that uncommon a text scanning situation.
With assignment expressions, it's a very natural if/elif chain:

for line in file:
if g := re.match(pat1, line):
croggle(g.group(1), 17)
elif g := re.match(pat2, line):
x = mugwump(g.group(3))
y = wumpus(g.group(2))
return defenestrate(x, y+3)
elif g := re.match(pat3, line):
# do something completely different with groups of g
elif g := re.match(pat4, line):
# more of the same

Without assigment expressions, it gets unspeakably ugly. You have to
use a deeply nested if/else if sequence where you match the regexp and
test the result on 2 separate lines at each branch, or reorganize the
code to use some kind of dispatch table (good if there's a lot more
than 4 regexps, but overkill for just 4), or whatever. I ended up
creating a special class instance just to match a regexp and remember
the result, so I could write in the if/elif style.

This kind of regexp matching is a common pattern and I keep wanting
assignment expressions whenever I code it, and end up crocking up some
silly workaround.
Jul 18 '05 #1
Share this Question
Share on Google+
23 Replies


P: n/a
On 14 Oct 2003 21:12:29 -0700, Paul Rubin wrote:
It gets annoying when there are 4 different regexps that the line
might match, and I want to do something different depending on which
one matches.


If you want to do lots of different things, you really should be placing
them in different functions:

def deal_with_line_type_A():
# do stuff for lines of type A

def deal_with_line_type_B():
# do stuff for lines of type B

This allows the tasks to be completely different for each type of line,
without cramming it into one structure.

Then, having defined what to do with each line type, map the regex to
the function for each type:

line_action = {
'AAA': deal_with_line_type_A,
'BBB': deal_with_line_type_B,
}

The dictionary then acts as the switchboard:

for regex in line_action:
match = re.match( regex, line )
if( match ):
line_action[regex](match)

Extending the range of lines is a matter of adding items to
line_actions, and writing the resulting function. The decision code
remains the same.

--
\ "Self-respect: The secure feeling that no one, as yet, is |
`\ suspicious." -- Henry L. Mencken |
_o__) |
Ben Finney <http://bignose.squidly.org/>
Jul 18 '05 #2

P: n/a
Ben Finney <bi****************@and-benfinney-does-too.id.au> writes:
If you want to do lots of different things, you really should be placing
them in different functions:


Yeah, I mentioned I could do something like that, but that it was
overkill for such a small list. Really, anywhere you have an
if/elif/elif/elif chain of any kind, you can probably replace it with
a lookup table. But the if/elif/elif idiom exists because a lot of
the time, it's the most natural and clear and correct way to write the
code. And this is just an obvious one of those instances, except it's
thwarted by a Python language deficiency that I hope will get
corrected someday.
Jul 18 '05 #3

P: n/a
On 14 Oct 2003 22:19:07 -0700, Paul Rubin wrote:
Ben Finney <bi****************@and-benfinney-does-too.id.au> writes:
If you want to do lots of different things, you really should be
placing them in different functions:
Yeah, I mentioned I could do something like that, but that it was
overkill for such a small list.


The example you gave was contrived, sure. But even it was getting
complex enough that it was hard to parse visually -- and using a switch
or case structure wouldn't have made it easier. The problem was the
fact that each case was doing something completely different.

Once each case is more complex than a smple statement or two, it makes
more sense to handle them in separate functions. If a task expands to
several statements, the likelihood is that it will keep expanding.
Better that it do so in a separate function rather than bloating some
monstrous switch structure.
But the if/elif/elif idiom exists because a lot of the time, it's the
most natural and clear and correct way to write the code.


Yes, when each case is trivially simple and easy to read along with all
the others, it does make sense to keep them together. The if/elif/else
structure works fine there.

That's not so for the example you gave, where each case was more complex
and differed sufficiently from the others that they were hard to see as
a single structure. Thus why I recommended using separate functions if
you want to do lots of different things.

--
\ "There is more to life than increasing its speed." -- Mahatma |
`\ Gandhi |
_o__) |
Ben Finney <http://bignose.squidly.org/>
Jul 18 '05 #4

P: n/a
Paul Rubin wrote:
Without assigment expressions, it gets unspeakably ugly.


The designers of Python believe that assignment expressions are bad
news (which I agree with), and they will NEVER make assigments into
expressions just to avoid this little problem.

Frankly, I think assignment expressions would cause far more
unspeakable ugliness than they would prevent.

There's workarounds. Live with them.
--
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
Jul 18 '05 #5

P: n/a
Paul Rubin wrote:
OK, I want to scan a file for lines matching a certain regexp. I'd
like to use an assignment expression, like

for line in file:
if (g := re.match(pat, line)):
croggle(g.group(1))

Since there are no assignment expressions in Python, I have to use a
temp var. That's a little more messy, but bearable: ... This kind of regexp matching is a common pattern and I keep wanting
assignment expressions whenever I code it, and end up crocking up some
silly workaround.


Indeed, this is one case where I have in fact used the pattern I
showed in more generic context in the Cookbook, something like (typing
the code back in from memory):

class Matcher(object):
def __init__(self, pat, *args):
self.re = re.compile(pat, *args)
self.mo = None
def __nonzero__(self):
return bool(self.mo)
def match(self, astr):
self.mo = self.re.match(astr)
return self.mo
def __getattr__(self, name):
return getattr(self.mo, name)

I'd rather inherit from the match object's type, but _sre doesn't
allow that; this containment + delegation is OK, anyway.

Note that my use is somewhat different from yours -- I prefer to
compile my re's at the start anyway, so what I do here is e.g.

ma1 = Matcher(pat1)
ma2 = Matcher(pat2)
for line in file:
if ma1.match(line): croggle(ma1.group(1))
elif ma2.match(line): plakke(ma2.group(2))

i.e., I prefer to keep separate matchers, one per re pattern.
If you prefer to have just one matcher:

ma = Matcher()
for line in file:
if ma.match(pat1, line): croggle(ma.group(1))
elif ma.match(pat2, line): plakke(ma.group(2))

that's perhaps even easier to arrange:

class Matcher(object):
def match(self, repat, astr):
self.mo = re.match(repat, astr)
return self.mo
def __getattr__(self, name):
return getattr(self.mo, name)

no need for __init__ or __nonzero__ (actually I'm not quite
sure WHY I had __nonzero__ last time I coded this -- maybe I
was also testing the matcher itself, not just the return of its
match method).
Alex

Jul 18 '05 #6

P: n/a
Paul Rubin wrote:
OK, I want to scan a file for lines matching a certain regexp. I'd
like to use an assignment expression, like

for line in file:
if (g := re.match(pat, line)):
croggle(g.group(1)) [...] It gets annoying when there are 4 different regexps that the line
might match, and I want to do something different depending on which
one matches. That's not that uncommon a text scanning situation.
With assignment expressions, it's a very natural if/elif chain: [...] This kind of regexp matching is a common pattern and I keep wanting
assignment expressions whenever I code it, and end up crocking up some
silly workaround.


If this is a common pattern in your code, then write an iterator class that
reads lines from a file and spits out the match object (+ tag, so you know
which regular expression was matched.
So your code becomes:

for match, tag in LineMatcher (...).parseFile (fname):
if tag == tag1:
action1
elif tag == tag2:
action2

cons: you have to invent names for every pattern
pros: patterns are compiled and thus more efficient

Daniel

Jul 18 '05 #7

P: n/a
Carl Banks wrote:
...
The real reason is that assignment expressions lead to all kinds of
ugly and unreadable code. This is because there is no linguistic
analogue for assignment as an expression. Things that work as


"""
Once upon a time, in a Kingdom far, far away, there was a
strong, corageous prince, who we'll call Richard, and his weak,
cowardly, but cunning younger brother, who we'll call John,
secretly hated and feated Richard and envied his strength.
One day, Richard and John set out on a fateful hunt in the woods
....
"""

Those clauses "who we'll call Richard" and "who we'll call John"
are exact natural-language equivalents of assignment-as-expression
(in a computer language with reference, not copy, semantics, of
course - but Python qualifies in this regard), or as close as
anything in natural language ever gets to computer languages.

Basically, I'm parentethically affixing a name to some entity
I'm describing, just so I can later use the name, rather than
some periphrasis, or a pronoun, with the well-known problems
that these can cause (computer languages don't have pronouns,
unless you want to consider perl's $_ as such perhaps...:-).

Of course there are alternatives (aren't there always, most
particularly in natural language?), such as claiming that you're
just informing the reader of the prince's "actual" name (but if
the kingdom was so far away, it's believable that the prince's
actual name was too hard to pronounce for us and "Peter" is just
a pseudonym you're using for convenience;-) -- but values in
computer languages don't have "actual names", in this analogy,
just "pseudonyms" anyway.

I'm not necessarily dissenting with your detestation of
assignment-as-expression (although gradually I'm getting some
doubts about the general, overall wisdom of Python's strong
distinction between expressions and statements, that's a more
general and problematic issue). But I _am_ dissenting with
your specific claim that "there is no linguistic analogue"
for it in natural language.
Alex

Jul 18 '05 #8

P: n/a
Carl Banks <im*****@aerojockey.invalid> writes:
Whatever. You're the only programmer I've ever encountered who claims
to have actual trouble understanding assignment expressions.
I really don't appreciate you putting words in my mouth, and I'm sorry
you feel the need to resort to dishororable tactics.

I claim assignment expressions are counterintuitive, and hard to read,
because they go against the grain of natural language. They require
more effort because we can't use the language parts of our brains to
help.


What does it mean to be hard to read? Your eyes can't make out the
characters on the screen? Or your eyes can make out the characters,
but the meaning conveyed isn't immediately clear to you. If the
latter, that means you claim to have trouble understanding the
expressions.
They require more effort because we can't use the language parts of
our brains to help.


Some of us either manage to limit our use them to ways where this
isn't a problem, or else it just isn't an issue to begin with.

Frankly your thing about no natural language analog sounds like hot
air to me. Have you got an analysis of every natural language ever
spoken in the world, that finds no construct like that? And even if
you do, where is the slightest evidence that it makes any difference?
Even if it does take an extra millisecond of mental effort to parse
the assignment expression, a workaround resulting from not using it
(such as defining a new class and making an instance of it and calling
some operation on it), being may take 100 times as much effort.
Jul 18 '05 #9

P: n/a
Alex Martelli wrote:
Carl Banks wrote:
...
The real reason is that assignment expressions lead to all kinds of
ugly and unreadable code. This is because there is no linguistic
analogue for assignment as an expression. Things that work as
"""
Once upon a time, in a Kingdom far, far away, there was a
strong, corageous prince, who we'll call Richard, and his weak,
cowardly, but cunning younger brother, who we'll call John,
secretly hated and feated Richard and envied his strength.
One day, Richard and John set out on a fateful hunt in the woods
...
"""

Those clauses "who we'll call Richard" and "who we'll call John"
are exact natural-language equivalents of assignment-as-expression
(in a computer language with reference, not copy, semantics, of
course - but Python qualifies in this regard), or as close as
anything in natural language ever gets to computer languages.

Basically, I'm parentethically affixing a name to some entity
I'm describing, just so I can later use the name, rather than
some periphrasis, or a pronoun, with the well-known problems
that these can cause (computer languages don't have pronouns,
unless you want to consider perl's $_ as such perhaps...:-).


Ok, I disagree that this is a suitable analogue. I'll explain.

My contention is that a large part of what makes something "readable"
in code is that is it resembles, to some degree, natural language.
This is because we can use the parts of our brain that parse natural
language to help us parse code. Makes sense, pretty obvious.

The thing is, these analogues have to match syntactically as well as
semantically. In other words, if the language construct in question
does not have an analogue that matches syntactically, then we have to
acquire the ability to parse it. Furthermore, if it turns out that
our "language circuits" are not able to internalize an unusual syntax,
then parsing it will always require intellectual effort. (Whether
this is true of assignment expression I won't speculate at this
moment.) In the end, we have something that is at least harder to
learn, and possibly takes more effort to read.

Now, your example does manage to communicate the semantics of
assignment expression (unlike Rubin's example, which didn't
communicate that anything was being assigned). However, I would say
your example still is not a proper analogy, for a very simple reason:
most people read computer programs as imperative, while your example
is declarative.

I hope I don't have to argue the point that most people think of
programming as imperative. I believe programmers think of "a=b" as
"Set a to b," not "a's value becomes b's value". Therefore, I don't
consider a declarative clause to be an analogue of an assignment; it
is both syntactically and semantically different.

Now, the question is, is there any way, syntactically, to have an
imperative in a relative clause? If so, can it be set in a relative
clause such that the object is also the antecedent? Certainly you
could *communicate* that with a detailed enough explanation, but can
you do it with analogous syntax? I would say no.

Another argument is the drop-in argument. In programming languages,
you are typically able to drop an expression anywhere an expression is
valid. The natural langauge analogue of an expression is a noun
phrase, and as in programming languages, it is syntactically valid to
drop a noun phrase anywhere a noun is expected.

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."
You cannot use either phrase as a noun phrase (you would have to
change them around). It follows that "a=b" is not suitable as an
expression.
[snip] I'm not necessarily dissenting with your detestation of
assignment-as-expression (although gradually I'm getting some
doubts about the general, overall wisdom of Python's strong
distinction between expressions and statements, that's a more
general and problematic issue). But I _am_ dissenting with
your specific claim that "there is no linguistic analogue"
for it in natural language.

Well, sorry, I'm standing by it. However, it got me to thinking.
Even if it did have a solid linguistic analogue, I still wouldn't like
it.

When I look at a statement or an expression, I prefer that I can look
at it and know that exactly ONE thing happens. Either it has a side
effect, or it returns a value: not both. (Although I'm not opposed to
stuff like readline(), which affect its file object and returns a
value, as long as the side effects are contained.) Assignment
expressions are, of course, the epitome of both at the same time,
which is the real reason I have such a distaste for them.

It would be really nice (generally, not Python in particular) if we
could have all things that return values be expressions, and all
things that have side effects be statements, AND be able to implement
it in a practical way.

I'm not sure if it's practical, thought; Ada does (or tries to do)
something like it, and it went a little too far.
--
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
Jul 18 '05 #10

P: n/a
Paul Rubin wrote:
Carl Banks <im*****@aerojockey.invalid> writes:
> Whatever. You're the only programmer I've ever encountered who claims
> to have actual trouble understanding assignment expressions.
I really don't appreciate you putting words in my mouth, and I'm sorry
you feel the need to resort to dishororable tactics.

I claim assignment expressions are counterintuitive, and hard to read,
because they go against the grain of natural language. They require
more effort because we can't use the language parts of our brains to
help.


What does it mean to be hard to read? Your eyes can't make out the
characters on the screen? Or your eyes can make out the characters,
but the meaning conveyed isn't immediately clear to you. If the
latter, that means you claim to have trouble understanding the
expressions.


No. Go look up the word understand. Whether assignment expressions
are easy to read, or hard to read, I can UNDERSTAND them just fine.

They require more effort because we can't use the language parts of
our brains to help.


Some of us either manage to limit our use them to ways where this
isn't a problem, or else it just isn't an issue to begin with.


Some of us have programmed in C or Lisp for a long time, and don't
realize how counterintuitive and awkward the construction is.

Frankly your thing about no natural language analog sounds like hot
air to me.


Go back a few posts, and you'll see I implored you to take my
linguistic argument as you would. You evidently felt it was
reasonable enough to argue with. If you'd like to dismiss it as crap,
be my guest. I'm here to defend my views, not to change your mind.
--
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
Jul 18 '05 #11

P: n/a
Carl Banks <im*****@aerojockey.invalid> writes:
No. Go look up the word understand. Whether assignment expressions
are easy to read, or hard to read, I can UNDERSTAND them just fine.
You're not making any sense. To understand an expression, you have to
read it first. So if it's hard to read, it's hard to understand.
Some of us have programmed in C or Lisp for a long time, and don't
realize how counterintuitive and awkward the construction is.


Then after you've programmed in C or Lisp for a while, maybe the
construction stops being counterintuitive and awkward, hmm? Sort of
like putting the adjective after the noun instead of before it is
counterintuitive for English speakers, but becomes intuitive if you
speak French for a while? If Python had those expressions too, they
would also become intuitive and non-awkward for Python programmers.

(Btw, I remember the exact moment when assignment expressions in C
became natural to me: When I first started learning C from Brian
Kernighan's C tutorial that explained

while ((c = getchar()) != '\0')
do stuff with c;

I had to spend a few moments understanding what was happening, but
then it made perfect sense. No long period of counterintuition or
awkwardness for me, thanks. So there's another counterexample to your
theory. In fact I had an "aha" when I saw that "a = b = c;" is also
an assignment expression in C and worked automatically for that
reason. In Python, of course, it's a special syntactic kludge with,
um, no natural language analog, not that that matters.)
Frankly your thing about no natural language analog sounds like hot
air to me.


Go back a few posts, and you'll see I implored you to take my
linguistic argument as you would. You evidently felt it was
reasonable enough to argue with. If you'd like to dismiss it as
crap, be my guest. I'm here to defend my views, not to change your
mind.


OK then, based on the decades of experience of millions of C and Lisp
programmers, I'll take your advice and dismiss your linguistic view as
crap. If you want to continue to embrace it, be my guest. Happy
crapping.
Jul 18 '05 #12

P: n/a
In article <6Z*************@nwrdny02.gnilink.net>,
Carl Banks <im*****@aerojockey.invalid> wrote:
....
My contention is that a large part of what makes something "readable"
in code is that is it resembles, to some degree, natural language.
This is because we can use the parts of our brain that parse natural
language to help us parse code. Makes sense, pretty obvious.

The thing is, these analogues have to match syntactically as well as
semantically. In other words, if the language construct in question
does not have an analogue that matches syntactically, then we have to
acquire the ability to parse it. Furthermore, if it turns out that
our "language circuits" are not able to internalize an unusual syntax,
then parsing it will always require intellectual effort. (Whether
this is true of assignment expression I won't speculate at this
moment.) In the end, we have something that is at least harder to
learn, and possibly takes more effort to read.
This part is less obvious. Syntactical relationships are learned,
and arguably learned in a very context sensitive way. Computer
programming languages are relatively simple and regular, and it
is not clear that they depend a lot on congruence with some natural
language.
Now, your example does manage to communicate the semantics of
assignment expression (unlike Rubin's example, which didn't
communicate that anything was being assigned). However, I would say
your example still is not a proper analogy, for a very simple reason:
most people read computer programs as imperative, while your example
is declarative.

I hope I don't have to argue the point that most people think of
programming as imperative. I believe programmers think of "a=b" as
"Set a to b," not "a's value becomes b's value". Therefore, I don't
consider a declarative clause to be an analogue of an assignment; it
is both syntactically and semantically different.
If we stipulate that we are talking about Python programmers, maybe.

In more general terms, though, I think it could be argued that
assignment actually doesn't play much of a role in natural speech
anyway, whether in the declarative or imperative sense. Unless
you count lexical function, but you're talking about syntax.
This should be bad news for Python, but by the time people get
here it doesn't matter much.

Moreover, I think you should probably quit while you're ahead,
because I have a hunch that the point you're pushing there would
actually work against you if it were more patently true. Suppose
the syntax actually were "set a to b", or of course more like
"set `a b" because this isn't Applescript or Cobol. Borrow the
time machine and make it so. Now, will this turn out to be an
expression? Very good odds, because now it's just a function.
Functions can be imperative, and they're certainly expressions.

Basically, I don't think you want to tie the quality of a computer
programming language to its congruence with English syntactical
forms. If there were a clear case for that, I think the FPL crowd
would come out way ahead.
When I look at a statement or an expression, I prefer that I can look
at it and know that exactly ONE thing happens. Either it has a side
effect, or it returns a value: not both. (Although I'm not opposed to
stuff like readline(), which affect its file object and returns a
value, as long as the side effects are contained.) Assignment
expressions are, of course, the epitome of both at the same time,
which is the real reason I have such a distaste for them.

It would be really nice (generally, not Python in particular) if we
could have all things that return values be expressions, and all
things that have side effects be statements, AND be able to implement
it in a practical way.

I'm not sure if it's practical, thought; Ada does (or tries to do)
something like it, and it went a little too far.


Probably didn't go near far enough. You have to get a look at
Haskell. Whether it's practical is endlessly debatable, and
I'm not sure it exactly does what you say there ... or maybe
you'd have to program in Haskell to see what you're saying.
But it is rather rigorous in this respect.

Donn Cave, do**@u.washington.edu
Jul 18 '05 #13

P: n/a
"Donn Cave" <do**@drizzle.com> writes:
But when you can say

if g := match(a, b):

then I suspect you will also be able to say things like -

if not (dv := start() and f := nfile(dv)
and ((t := f.find("--") > 0 and fx = f[:t]) or (fx = f))):
print "Well, bless me!"


Well, yes, you can write messy code in any language. There will
always be some need for tastefulness in programming. Language
designers can't make that need go away.
Jul 18 '05 #14

P: n/a
Donn Cave wrote:
In article <6Z*************@nwrdny02.gnilink.net>,
Carl Banks <im*****@aerojockey.invalid> wrote:
...
My contention is that a large part of what makes something "readable"
in code is that is it resembles, to some degree, natural language.
This is because we can use the parts of our brain that parse natural
language to help us parse code. Makes sense, pretty obvious.

The thing is, these analogues have to match syntactically as well as
semantically. In other words, if the language construct in question
does not have an analogue that matches syntactically, then we have to
acquire the ability to parse it. Furthermore, if it turns out that
our "language circuits" are not able to internalize an unusual syntax,
then parsing it will always require intellectual effort. (Whether
this is true of assignment expression I won't speculate at this
moment.) In the end, we have something that is at least harder to
learn, and possibly takes more effort to read.
This part is less obvious. Syntactical relationships are learned,
and arguably learned in a very context sensitive way.


Well, I can assure you that it's at least harder to learn, seeing that
learning a new syntax is always harder than using syntax similar to
what you already know. (Otherwise, explain why Spanish is easier to
learn for English speakers than Japanese.)

As for the argument that it could take more effort, let's just
remember that our internal language circuits cannot handle arbitrary
syntax. Simple as assignment expressions are, I'm not so sure our
language circuits can parse a syntax which doesn't exist in any
language I know of (and I suspect doesn't exist in any language). If
we cannot parse an assignment expression though ordinary language
processing, then it follows that it takes more effort to read it.

(I sense we're getting dangerously close to introducing Chomsky into
this discussion; if so, I'm outta here.)

Computer
programming languages are relatively simple and regular, and it
is not clear that they depend a lot on congruence with some natural
language.
I highly disagree with this statement, however.

Relatively simple and regular has nothing to do with it. Assembly
language is relatively simple and regular. Intercal is relatively
simple and regular. Perl is relatively simple and regular. And
they're all unreadable messes. (Even still, all of them rely on a
smittering of resemblance to natural language.)

There's a reason hardly any successful programming languages eschew a
resemblance to human language: because humans are good at thinking in
terms of language.

I hope I don't have to argue the point that most people think of
programming as imperative. I believe programmers think of "a=b" as
"Set a to b," not "a's value becomes b's value". Therefore, I don't
consider a declarative clause to be an analogue of an assignment; it
is both syntactically and semantically different.


If we stipulate that we are talking about Python programmers, maybe.

In more general terms, though, I think it could be argued that
assignment actually doesn't play much of a role in natural speech
anyway, whether in the declarative or imperative sense.


You're completely missing the point.

I'm not trying to claim that assignment, per se, plays a role in
natural speech. My claim is that assignment is a command. When a
programmer writes a=b, he's commanding the computer to set a to b.
Commands do play a role in natural speech, and only the imperative
mood conveys it (without descriptive circumlocations).

Which is (getting back to the point) why I think Martelli's example
was incorrect.
[snip] Basically, I don't think you want to tie the quality of a computer
programming language to its congruence with English syntactical
forms. If there were a clear case for that, I think the FPL crowd
would come out way ahead.


Basically, I think you're missing the whole point of what I'm saying,
and are therefore ill suited to judge the strength of my position.
--
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
Jul 18 '05 #15

P: n/a
In article <7x************@ruckus.brouhaha.com>, Paul Rubin wrote:
"Donn Cave" <do**@drizzle.com> writes:
But when you can say

if g := match(a, b):

then I suspect you will also be able to say things like -

if not (dv := start() and f := nfile(dv)
and ((t := f.find("--") > 0 and fx = f[:t]) or (fx = f))):
print "Well, bless me!"


Well, yes, you can write messy code in any language. There will
always be some need for tastefulness in programming. Language
designers can't make that need go away.


Of course. But what I think a lot of people miss is that language design is,
in some ways, an experiment on human behavior, with programmers as the
subjects. If you wrote a language, and found that adding one particular set
of features as opposed to another set of features resulted in code that,
overall, you preferred to look at, you might prefer to design the language
that way. Regardless of whether or not you trust yourself (or others) to
use/abuse the features available.

Some languages prefer to let the programmer do anything. This makes
programmers very happy, because they have the freedom to do whatever they
want. However, it also means that it's more difficult to read other people's
code, because they have that same freedom. There's more variance.

As a programmer, you already have the freedom to pick the language you want.
If your job doesn't allow it, you can pick another job. Or you can start
your own company, or program as a hobby. No language designer is telling you
what to do; you are making the choice to pick a given language, ultimately.

But from the perspective of a language designer, your decisions affect the
code that other people will produce. By adding a single feature, you may be
indirectly creating 10,000 actual usages of that feature in other people's
code. In a sense, you are programming the programmers, and if you make
things possible in your language, your programmers will do those things. If
it turns out to be a fault, this reflects directly on you.

This is, I think, the fundamental reason for the statement vs. expression
dichotomy in Python. It's not that clear statements can't be written with
embedded statements. It's that Guido doesn't want to have to read other
people's code written that way (I'm guessing - feel free to unstuff these
words from Guido's mouth if I'm in error ;), and he certainly doesn't want
the "everyone" to which his "computer programming for everyone" refers to
have to read code written that way. It's a problem for some people. He
wanted a language that didn't pose that problem for those people.

In the end, I fullheartedly recommend against taking an antagonistic
viewpoint against language designers because they don't support Feature X.
They didn't write the language for you; if they did, they would have
included Feature X, because obviously it's important to you. But instead,
they saw (hopefully) the greater picture; the gigantic body of code that
others would go on to produce. By designing a language in a particular way,
language authors in effect design this body of code as well.

For instance, I personally think Python would be even better than it is if
it had code blocks. I'm aware that this probably won't happen. But I
understand why, and it has nothing to do with *me*. So, I don't take it
personally. Besides, Python is free, and it rocks, and it makes me happy
because it puts my code so much closer to my thoughts than any other
language. Python targets a particular demographic, and it managed to find
one which I belong to, to a fairly large degree.

But when I want statements in my lambdas, I'll have to look elsewhere.
This means I might play around with Ruby, or ActionScript, or SmallTalk, to
get a taste of that. And if I want assignment expressions, maybe I'll try
Java or C++. But I don't find myself wanting for those often... or ever...

--
..:[ dave benjamin (ramenboy) -:- www.ramenfest.com -:- www.3dex.com ]:.
: d r i n k i n g l i f e o u t o f t h e c o n t a i n e r :
Jul 18 '05 #16

P: n/a
Carl Banks wrote:
...
syntax. Simple as assignment expressions are, I'm not so sure our
language circuits can parse a syntax which doesn't exist in any
language I know of (and I suspect doesn't exist in any language). If


Hmmm, did my msg of 2 days ago to this thread get lost in the ether?

"""
Once upon a time, in a Kingdom far, far away, there was a
strong, corageous prince, who we'll call Richard, and his weak,
cowardly, but cunning younger brother, who we'll call John,
secretly hated and feated Richard and envied his strength.

One day, Richard and John set out on a fateful hunt in the woods
....
"""

etc, etc. I didn't see any answer to that -- and I see you keep
claiming that "parenthetically giving a name to some entity
described in discourse" is a construct which may not exist in
any natural language. In NL you might claim Richard "WAS _the_
name" of the guy, rather than just a monicker WE use for him,
but if the kingdom was sufficiently far away it might make
perfect sense to accept his "real" name is unpronounceable to
us (or forgotten in history, if the time was long enough ago)
so that "Richard" is just a convention we'll use. You often
also see parenthetical remarks such "this truly evil monopolist
corporation, which I'll call Microfost to protect the innocent",
and the like (explicitly and still parenthetically introducing
a pseudonym). When you're talking about objects which can't
claim to "have REAL names" (as people are sometimes conceived
to do, as firms legally do, etc) -- and when you _cannot_ use
pronouns (as opposed to just wanting to minimize their use to
minimize referential ambiguity) -- the choice is pretty much
down to introducing such pseudonyms or keep using periphrasis
over and over again, most tediously. These conditions are more
often met in technical and scientific discourse, which still
remains a perfectly good example of natural language: "the net
expected discounted present value of the whole predicted cash
flow, which we'll call NPV, plays a crucial role in rational
investment decisions". Also "(NPV for short)" in lieu of
", which we'll call NPV", quite similarly.

So, whatever your arguments against assignment-as-expression,
I just don't think "it's not in natural language" has any
validity to it.
Alex

Jul 18 '05 #17

P: n/a
Ah, I _knew_ there had to be some response -- just like Usenet to delay
its delivery. Darn. OK, here goes -- sorry for the repetition...:

Carl Banks wrote:
...
Once upon a time, in a Kingdom far, far away, there was a
strong, corageous prince, who we'll call Richard, and his weak,
... Ok, I disagree that this is a suitable analogue. I'll explain.

My contention is that a large part of what makes something "readable"
in code is that is it resembles, to some degree, natural language.
We disagree on this general principle -- which I guess makes the
whole discussion somewhat moot, but I'm more interested in the
specific disagreement about your contention that assignment - as -
expression has no analog in natural language.
This is because we can use the parts of our brain that parse natural
language to help us parse code. Makes sense, pretty obvious.
That's the thesis on with Perl was designed -- by Larry Wall, whose
background, I believe, is in linguistics. Ambiguities resolved by
context, _pronouns_ (!) such as $_, chaotic redundancy just like in
natural language -- the works. I do not find the result very readable
at all, even though I do concede that the resemblance to the maddening
wonderful chaos of natural language IS occasionally quite amazing.
The thing is, these analogues have to match syntactically as well as
semantically. In other words, if the language construct in question
does not have an analogue that matches syntactically, then we have to
acquire the ability to parse it. Furthermore, if it turns out that
our "language circuits" are not able to internalize an unusual syntax,
then parsing it will always require intellectual effort. (Whether
I can posit this if it helps discussion -- I may not fully agree but
quibbling would be distracting and irrelevant here.
this is true of assignment expression I won't speculate at this
moment.) In the end, we have something that is at least harder to
learn, and possibly takes more effort to read.
Ditto.

Now, your example does manage to communicate the semantics of
assignment expression (unlike Rubin's example, which didn't
communicate that anything was being assigned). However, I would say
I agree on both scores.
your example still is not a proper analogy, for a very simple reason:
most people read computer programs as imperative, while your example
is declarative.
Not very relevant, because the syntactic and semantic parallels
in natural language (as well as, where expressions and "single
assignment" are concerned, in programming languages) between the
declarative and imperative moods are SO close.

I hope I don't have to argue the point that most people think of
programming as imperative. I believe programmers think of "a=b" as
"Set a to b," not "a's value becomes b's value". Therefore, I don't
Programmers whose early training was in copy-semantics languages
may have such trouble, but that's got nothing to do with the issue.
(And I strongly doubt that copy vs reference semantics makes a
huge difference anyway, see sundry counterexamples passim).

In reference-semantics languages such as Python, the right way to
read "a = ..." is "in the following we'll use name 'a' to mean ...",
or more succint readings when meaningful in context, e.g. I've heard
people read
mean = total / number_of_items
as "The mean IS the total divided by the number of items", i.e. as
if the statement was reminding the reader of what "mean" MEANS.
consider a declarative clause to be an analogue of an assignment; it
is both syntactically and semantically different.
You may substitute the declarative "we'll use name X to mean ..."
with the imperative "use name X to mean ..." without any substantial
change in either semantics OR syntax. "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" -- though of course it reads right to left, as
function calls so often do, since their arguments, which we write to
the right of the function name, are to be evaluated BEFORE the call
(strict ordering) so it may be convenient in a NL equivalent to
mention them before the action (different NL's have different
verb / noun ordering preferences, of course -- I hope you're not
claiming that German programmers prefer RPN beause of this?-).

Particularly in Romance languages, and in learned moods of discourse,
we tend to use a LOT more parenthetical and subordinate phrases than
you may be used to in contemporary English (my own style typically
betrays that -- even though I think in English when I write in English,
it's an English with VERY intricate, Romance-like phrase structure;-).
A historical and cultural accident, nothing very deep: read (ah joy!)
Gibbons, or Adam Smith, or (eek) Ricardo, to see how learned English
prose could be in the 18th century... not noticeably less intricate
in phrase-structure than Romance languages (indeed, some _French_
authors of that time -- though no Italian ones -- had snappier and
simpler phrase structure than their British contemporaries, IMHO).

MOST definitely, nothing ANYWHERE as deep that you can justify your
exaggerated claims about "assignment expressions" being so utterly
foreign to natural language!!!

Now, the question is, is there any way, syntactically, to have an
imperative in a relative clause? If so, can it be set in a relative
clause such that the object is also the antecedent? Certainly you
could *communicate* that with a detailed enough explanation, but can
you do it with analogous syntax? I would say no.
I'm not sure what relative clauses have to do with this all. We're
talking about an imperative to use name X for an object that is being
described and about which other imperatives are expressed within the
same sentence; that will typically be a parenthetical (set off with
either commas or parentheses in written language, but pronounced in
just about the same way in spoken, i.e. really natural, language,
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". Or if you're so stuck on word-order
(silly when making generalized claims about natural languages, since
NOTORIOUSLY different natural languages have such different preferred
word orderings!), "The NPV, always call discounted net present
value that!, you must make very appetizing", or "Do present
a very appetizing NPV, always call discounted net present value
that way!, to make the suits happy".

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.

Another argument is the drop-in argument. In programming languages,
you are typically able to drop an expression anywhere an expression is
valid. The natural langauge analogue of an expression is a noun
phrase, and as in programming languages, it is syntactically valid to
drop a noun phrase anywhere a noun is expected.

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! "Agent X, for which role you'll hire Mr Smith, you'll
liaise daily with" -- these are instructions to a secret agent
and are no less imperative than any snippet of programming, and
even though the future tense means some syntactical ambiguity
between commands and predictions, no natural language speaker
will understand this sentence any different than the two.
"1. hire Mr Smith as Agent X; 2. liaise daily with Agent X".
So much for your attempt at strict imperative/declarative
distinction in natural language... the distinction is in fact
NOT very strong at all in more cases than not! Much of the
clues about what's a command and what's a statement of facts
as they are, an explanation of why they are that way, etc, are
in NL utterances' context (and pragmatics, including social
distinctions between speaker and listener, etc, etc).

"The blond guy, who wants to be called Bob, you must not kill",
vs "The blond guy, call him Bob, you must not kill", "Do not
kill Bob, the blond guy", etc, etc -- all perfectly good NL
sentences, all with obviously identical semantics, minor and
irrelevant changes in surface syntax (word order etc). And
all perfectly good examples of "assignment expressions".
You cannot use either phrase as a noun phrase (you would have to
change them around). It follows that "a=b" is not suitable as an
expression.
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.

[snip]
I'm not necessarily dissenting with your detestation of
assignment-as-expression (although gradually I'm getting some
doubts about the general, overall wisdom of Python's strong
distinction between expressions and statements, that's a more
general and problematic issue). But I _am_ dissenting with
your specific claim that "there is no linguistic analogue"
for it in natural language.
Well, sorry, I'm standing by it. However, it got me to thinking.
Even if it did have a solid linguistic analogue, I still wouldn't like
it.


I think you're being so utterly and totally unreasonable by
denying the "blond guy (call him Bob!)" strict NL analogy to
assignment expressions, that I'm having to make a very deliberate
effort to not start LIKING assignment expressions just to make
you sorry about being so unreasonable:-). I won't, but I'll
keep arguing against you just because...:-).

Giving a local name to some value has no "side effects" that
are any less "contained" than your "not opposed to" example:
When I look at a statement or an expression, I prefer that I can look
at it and know that exactly ONE thing happens. Either it has a side
effect, or it returns a value: not both. (Although I'm not opposed to
stuff like readline(), which affect its file object and returns a
value, as long as the side effects are contained.) Assignment
In fact, as long as you never RE-bind a name ("single assignment"),
giving something a name is perfectly OK even in the purest functional
NO-such-thing-as-a-side-effect language.
expressions are, of course, the epitome of both at the same time,
which is the real reason I have such a distaste for them.
"Side effect" is the mutation of some state. A name is not a state
(unless you object specifically to *RE-binding* names -- quite a
different issue). I see Donn already suggested you look into Haskell,
with "state changing" closely limited to monads. But if you do,
you'll probably have to drop any illusions about this having just
about anything to do with natural language analogies!

If you think of "results" and "side effects" of instructions being
given in natural language and faithfully followed, you'll be hard
put to draw any distinction -- because it's a distinction that
belongs more to the realm of _maths_, than to the messy real world
and the messy natural language evolved to deal with the real world.
Any RW action has N consequences, and sometimes discerning which of
those are (intended) "results" and which (unintended or deemed to
be unimportant) "side effects" is close to impossible, requiring
mind-reading perhaps all the way to the subconscious (I go get a
coffee, with the "results" of getting caffeine in me and the "side
effect" of taking a short break from work -- hmmm.... are you SURE
that "side effect" was as unintended and accidental as all that...?-).

It would be really nice (generally, not Python in particular) if we
could have all things that return values be expressions, and all
things that have side effects be statements, AND be able to implement
it in a practical way.

I'm not sure if it's practical, thought; Ada does (or tries to do)
something like it, and it went a little too far.


I think it's an issue of doing things in a rigorous mathematic
framework, and that Ada's failure, like many other language's, is
to try to be "rigorous" in what's really a very ad-hoc way.
Python doesn't really try to be rigorous and has good pragmatical
reasons for such limitations as the expression/statement schism
(though sometimes they may feel confining, of course, depending
on what one was previously used to). IMHO, of course.
Alex

Jul 18 '05 #18

P: n/a
To me, simple var=val assignments often correspond to idiomatic
Emglish sentences.
"If your answer to my question is correct, your reward will be three
times the value of that answer" translates to something like
if (answer=response(question)) == question.correct_answer: reward =
3*answer

However, unpacking assignment (which C lacks) strikes me as more
problematical.
def f(): yield 1; yield 2 .... a,b = f()


If this assignment statement were to be an expression, what should be
its value? The exhausted generator-iterator produced by f()? That is
gone, I believe, before the actual assignment. The tuple (a,b)? That
never exists in the current implementation of the statement. Or do we
arbitrarily pick the first or last item assigned.

In Python, even single assignment can be problematical when targets
(lvalues in C) mutate (which, again, I believe impossible in C).
Consider
obj.val = 3
where obj.__set/get/attr__ are such that obj.val returns 7. If we
were to make that statement an expression, should it return the value
given to obj (3) or the value that obj.val results as (7), and which
will be used in following statements?

Terry J. Reedy
Jul 18 '05 #19

P: n/a
Alex Martelli wrote:
Ah, I _knew_ there had to be some response -- just like Usenet to delay
its delivery. Darn. OK, here goes -- sorry for the repetition...:

Carl Banks wrote:
...
Once upon a time, in a Kingdom far, far away, there was a
strong, corageous prince, who we'll call Richard, and his weak, ...
Ok, I disagree that this is a suitable analogue. I'll explain.

My contention is that a large part of what makes something "readable"
in code is that is it resembles, to some degree, natural language.
We disagree on this general principle -- which I guess makes the
whole discussion somewhat moot, but I'm more interested in the
specific disagreement about your contention that assignment - as -
expression has no analog in natural language.


Very well.

This is because we can use the parts of our brain that parse natural
language to help us parse code. Makes sense, pretty obvious.


That's the thesis on with Perl was designed -- by Larry Wall, whose
background, I believe, is in linguistics. Ambiguities resolved by
context, _pronouns_ (!) such as $_, chaotic redundancy just like in
natural language -- the works. I do not find the result very readable
at all, even though I do concede that the resemblance to the maddening
wonderful chaos of natural language IS occasionally quite amazing.


Yes, I've read about this. I don't object to that approach, but I do
object to the priorities. I would advocate having a simple, minimal
grammar that stays inside the set of natural grammatical structures.
Obviously, that's not what Perl is doing.

The thing is, these analogues have to match syntactically as well as
semantically. In other words, if the language construct in question
does not have an analogue that matches syntactically, then we have to
acquire the ability to parse it. Furthermore, if it turns out that
our "language circuits" are not able to internalize an unusual syntax,
then parsing it will always require intellectual effort. (Whether


I can posit this if it helps discussion -- I may not fully agree but
quibbling would be distracting and irrelevant here.
this is true of assignment expression I won't speculate at this
moment.) In the end, we have something that is at least harder to
learn, and possibly takes more effort to read.


Ditto.

Now, your example does manage to communicate the semantics of
assignment expression (unlike Rubin's example, which didn't
communicate that anything was being assigned). However, I would say


I agree on both scores.
your example still is not a proper analogy, for a very simple reason:
most people read computer programs as imperative, while your example
is declarative.


Not very relevant, because the syntactic and semantic parallels
in natural language (as well as, where expressions and "single
assignment" are concerned, in programming languages) between the
declarative and imperative moods are SO close.


Well, the thing is, you could find any similarity you want and claim
it's an analogy. But I say not any analogy will do. If a programmer
reads "a=b" and parses it as an imperative, then imperative is the
only analogue that works here (according to my contention, which you
don't agree with, making this whole discussion moot), no matter how
close the syntax or semantics are to the declarative case.

To be honest, I'm not so sure I used the right word in "analogue."
I'm looking more for an exact verbal description of the code, using
the same syntax (noun phrase for an expression, etc.) as programmer
internally parses it as when he reads.

My contention makes a lot more sense when you use this as the
definition of analogue.

I hope I don't have to argue the point that most people think of
programming as imperative. I believe programmers think of "a=b" as
"Set a to b," not "a's value becomes b's value". Therefore, I don't


Programmers whose early training was in copy-semantics languages
may have such trouble, but that's got nothing to do with the issue.
(And I strongly doubt that copy vs reference semantics makes a
huge difference anyway, see sundry counterexamples passim).


Yes.

I suspect most people see "a=b" and internally parse it as something
simple like "set a to b" or "let a equal b", filling in the semantic
details afterwards. That's why I haven't been careful not to say "set
a to b" when I should be saying "set a to the value of b".

In that light, the semantics (copy or reference or whatever) of
assignment are irrelevant to my argument. The only thing that's
relevant is what goes on in a person's head when reading "a=b".
[snip]
consider a declarative clause to be an analogue of an assignment; it
is both syntactically and semantically different.


You may substitute the declarative "we'll use name X to mean ..."
with the imperative "use name X to mean ..." without any substantial
change in either semantics OR syntax.


First of all, the command here is a command to the computer, not to
us. So the declarative sentence with the same semantics would be "the
computer uses X to mean ...".

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
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).
[snip] 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?

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..."

Now, the question is, is there any way, syntactically, to have an
imperative in a relative clause? If so, can it be set in a relative
clause such that the object is also the antecedent? Certainly you
could *communicate* that with a detailed enough explanation, but can
you do it with analogous syntax? I would say no.


I'm not sure what relative clauses have to do with this all.


Well, that's what you used.

We're
talking about an imperative to use name X for an object that is being
described and about which other imperatives are expressed within the
same sentence; that will typically be a parenthetical (set off with
either commas or parentheses in written language, but pronounced in
just about the same way in spoken, i.e. really natural, language,
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
sound quite as good in an exact verbal description. I also think the
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.

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

"observe a--set it to b"

Doesn't sound to good to me--it sounds as if you could set a before or
after observing it--so it's not likely to be how a programmer would
parse the code. It also happens to violate the drop-in argument.

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.

Another argument is the drop-in argument. In programming languages,
you are typically able to drop an expression anywhere an expression is
valid. The natural langauge analogue of an expression is a noun
phrase, and as in programming languages, it is syntactically valid to
drop a noun phrase anywhere a noun is expected.

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.
[snip more stuff claiming that declarative and imperative are the same]
You cannot use either phrase as a noun phrase (you would have to
change them around). It follows that "a=b" is not suitable as an
expression.


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.
Not only that, rewording it changes the syntax in a non-trivial way.
Consider the following rewording:

if a, which the computer sets to b, is equal to 0

Notice that a is in the if-clause, whereas b and the assignment are in
the relative clause. A verbal analogue with the same syntax should
have a in relative clause along with b and the assignment, because
that's what assignment expressions do:

if (a = b) == 0

The analogous code to the rewording would look like this:

if a (= b) == 0

I actually find this slightly more readable, even though the syntax is
less familiar. I believe the reason for this is the odd grouping
actually suggests to me to parse it like the relative-clause-based
rewording. (Of course, I'm self-conscious now.)

Do you understand what I mean by drop-in replacement now?

[snip]
I'm not necessarily dissenting with your detestation of
assignment-as-expression (although gradually I'm getting some
doubts about the general, overall wisdom of Python's strong
distinction between expressions and statements, that's a more
general and problematic issue). But I _am_ dissenting with
your specific claim that "there is no linguistic analogue"
for it in natural language.


Well, sorry, I'm standing by it. However, it got me to thinking.
Even if it did have a solid linguistic analogue, I still wouldn't like
it.


I think you're being so utterly and totally unreasonable by
denying the "blond guy (call him Bob!)" strict NL analogy to
assignment expressions, that I'm having to make a very deliberate
effort to not start LIKING assignment expressions just to make
you sorry about being so unreasonable:-). I won't, but I'll
keep arguing against you just because...:-).


Well, sorry. Obviously, if one has a very loose definition of
analogy, one can make language do just about anything. The problem
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?

[snip rest of philosophying which I mostly agree with]
--
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
Jul 18 '05 #20

P: n/a
Carl Banks wrote:
...
You may substitute the declarative "we'll use name X to mean ..."
with the imperative "use name X to mean ..." without any substantial
change in either semantics OR syntax.
First of all, the command here is a command to the computer, not to
us. So the declarative sentence with the same semantics would be "the
computer uses X to mean ...".


"The computer" is wildly inappropriate here. "This program", or
"this scope of this program", maybe. But "we" is far closer to
how natural language speakers would normally express themselves --
joining the listener and the teller in a plural is a good and
very basic trick of storytelling. Plus, if you want imperative
mood, "Take X to mean..." (slightly more specific than "use")
may be fine.

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.
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. Many phrasings of the same
command or description -- which may differ in surface syntax, e.g in
word-order, partly depending on exactly what natural language they're
using, are perfectly equivalent and easily parsed as such by native
speakers of the respective languages. You can't [1] blithely ignore the
last century-plus of linguistics and claim "no analogue" between, e.g,
"give John the bread", "give the bread to John", "To John, give the bread",
"The bread, give to John", &c. Prepositions and conjunctions may be needed
in one turn of phrase, optional in another, dropped in yet another, but
that makes no deep difference to the phrases' understandability to native
speakers -- more often than not, alternative surface syntax may just carry
different connotations (as opposed to denotations), emphasizing one aspect
rather than another, as appropriate in pragmatics and by context.

[footnote 1]: well of course you CAN blithely ignore whatever you wish,
but you sure cannot do so AND seriously hope to maintain any shred of
credibility at one and the same time.

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". 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".

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.

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"; 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.

So, any claim that "kiss cinderella, the fairest of them all"
is not an "analogue" to
kiss( cinderella := fairest(themall) )
_just doesn't 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:-)].

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.
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)
??? Using sensible 'transliterations', you'd read "if (a:=b+c)==0:" as:
if a, which is b+c, equals zero, ...
and that call to foo as something like
[call] foo, naming as 'bar' 23, [and] naming as 'baz' 45

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 -- 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.

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"?!?!?!
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? Of course, in a formal mood you'd use
such formal-sounding phrasings as "X, defined as Y, ..." rather than such
informal-sounding ones as "Y, call it X, ...". But both formal AND
informal moods are perfectly good parts of natural language, and why
"informal" is often more easily readable to a reader sharing cultural
traits with the writer, "formal" may in fact be easier in certain cases
where such sharing can't be assumed (I'm reminded of a "Jeeves and
Wooster" tidbit -- Jeeves, visiting the US, orders a glass of juice, the
waitress replies "you've got it!", and Jeeves, quite perplexed, starts
looking around the counter and objects that, no, he _hasn't_!-).

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, 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.
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.

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

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).

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.

"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?!
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. 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). So, you have all the drop-in replacement
you want, and, were your objection TRULY based on this line of thought,
you should now be jumping to campaign FOR assignment expressions
as long as they were spelled "a:=b"...?-)

keep arguing against you just because...:-).


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.
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.

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 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!-)
Alex

Jul 18 '05 #21

P: n/a
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
Jul 18 '05 #22

P: n/a
Carl Banks wrote:
...
"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


IF a programmer is so utterly obtuse and obdurate as to be unable
to "read" := as 'call it', 'is', 'becomes', 'which is', and so on
ad nauseam (any of the bazillion natural-language analogues I've
shown), and so narrow-minded, as you claim, that he or she will
keep stubbornly reading it as a "set to" which is NEVER appropriate,
then MAYBE that subnormal programmer will have a slightly harder
time learning ':=' than he or she has learning other constructs.

Miraculously, of course, said programmer HAS learned to "read"
e.g. % as meaning 'modulo' in some expressions and 'formatting'
in others; 2:7 as "2 maps to 7" within braces, but as "from 2
to 7" within brackets; parentheses meaning tuple here, function
call there, class inheritance yonder; and so on, and so forth --
yet that paragon of mental flexibility, so GOOD at reading the
SAME construct in different appropriate ways depending on
context, has an inexplicably localized blind spot in reading
two DIFFERENT constructs, = vs := , in two different and
appropriate ways -- truly wondrous to behold.

Yeah, well, given his/her incredibly-conveniently-located immutable
blind spot, said inDUHvidual WILL have some learning problems
connected to that one immutable blind spot. Surprise, surprise.

I don't agree with the likelihood of any of these hypotheses
for one second (and I suspect I've taught programming to more
newbies than you have), but, no matter. What DOES matter, is
that no shred is left of the "no analog in natural language"
assertion -- indeed, you now say:
though it's completely analogous.


Oh *GOOD*. COMPLETELY. Wow, we do agree. All that's left is
your unsupported hypothesis that programmers are likelier to
have a blind spot here than anywhere else. I disagree. I do
not intend to fund a study to find out, either:-). Please find
other NON-natural-language related ways to attack your pet-hate
assignment-expression and its ilk.
Wrapping up -- I disagree that saying "a is b" is inappropriate.
You keep talking about RE-binding of name a, but that's not
necessarily what's happening. It's also quite possible that a
had previously no binding. In any case, the implied "from now
on, until further notice" can cancel the difference (in fact,
single-assignment languages HAVE some empirical support as
being easier to learn, if I recall correctly -- subjectively,
I recall from my very first attempt at Fortran, well over a
quarter century ago, that the ONE construct that stumped me a bit
was exactly "X = X + 1", the kind of construct that single
assignment languages deliberately do NOT have -- oh well,
anyway, just a digression).

You claim I earlier agreed that saying "a is b" does not clearly
communicate assignment. I don't think I did, and I suspect
that if you read that into my words I may have expressed myself
in unclear ways (unless it was a blind spot on your part:-).
Sure, longer words and phrases "stand out" more, but that's a
matter of emphasis and connotation, not one of denotation.
Alex

Jul 18 '05 #23

P: n/a

"Carl Banks" <im*****@aerojockey.invalid> wrote in message
news:TV*****************@nwrdny02.gnilink.net...
foo(bar=23, baz=45)
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,
On the contrary, besides the call, assignment is all there is. bar
and baz are bound to 23 and 45 either in foo's local namespace (if
they appear in foo's arg list) or in foo's **dic (if they are not in
the arg list and there is a **dic in the arg list) or an error is
raised .

Assignment expressions differ from assignment statements in that they
*also* 'return' the value to the expression's context as the value of
the expression. They 'tee' the righthand expression result to both
the name binder and the local context. In function calls like above,
there is no teeing. The call is *not* the same as foo(23,45) unless
bar and baz happens to be the first two positional params.

Compare this with
while (a=next()) != 3:
For the purpose of computing the condition, this is the same as
while next() != 3:
The assignment is only a side-effect allowing possible later use of
the value assigned, after it is used first to resolve the condition
expression. The assigment expression might better be written
while (a=)next() != 3:
to emphasize the double use of next's return value.

In the function call, the assignment for later use is all there is.
There is no teeing for immediate use.
Incidentally, default arguments in a function definition is a lot
worse--a lot of people do take them as assignments,
Which they are.

Default object assignments are much like call keyword assigments in
that the expression is evaluated outside of the function's locals
while the binding is done within the function's locals.
and are surprised when their code doesn't work as expected.


The confusion results from Python function objects have two types of
'runtime': one definition/construction time and 0 to many
call/execution times.

The assignment works exactly as expected, but is done only once at
construction time instead of once at each of possibly many execution
times. If a def is run multiple times to generate multiple function
objects, then the defaults are recalculated (in the def's context) for
each function object, but still only once for each.

Terry J. Reedy
Jul 18 '05 #24

This discussion thread is closed

Replies have been disabled for this discussion.