[net.lang] Multiple assignments

franka@mmintl.UUCP (Frank Adams) (05/12/86)

In article <797@bentley.UUCP> kwh@bentley.UUCP writes:
>In article <501@brl-smoke.ARPA> rbj@icst-cmr (Root Boy Jim) writes:
>>And as someone pointed out, assignments return a value too, so should we
>>cast them to void as well?  Oh yeah, assignment is `different'.
>
>Actually, this does bother me somewhat.  I think I prefer the idea that
>values should be used or explicitly discarded, as in forth.  (Not that forth
>has any error checking!)  No, I'm not suggesting that lint should complain
>about assignments, or that C should have a different notation for assignments
>that are being pipelined into another expression.  Just waiting for the next
>generation of languages.

This bothers me somewhat too.  I do have a suggestion for how to deal with
it: have a "multi-assignment" operator.  Supposing that "$" is being used
for this operator, then to set both "a" and "b" to zero, one would write
"a $ b = 0", rather than "a = b = 0", as C does.  This has the disadvantage
that it cannot be used where the result of the assignment is used
immediately in a calculation (e.g., "a = 2 * b = sqrt(c)").  On the other
hand, if your language supports argument passing by address, it permits an
output argument to be multiply assigned; something which
assignment-with-value does not support.

I am not recommending that this be put into C.  It is an idea for new
languages.  Accordingly, I have directed follow-ups to net.lang instead of
net.lang.c.

Frank Adams                           ihnp4!philabs!pwa-b!mmintl!franka
Multimate International    52 Oakland Ave North    E. Hartford, CT 06108

lkw@csun.UUCP (Larry Wake) (05/16/86)

Keywords:

In article <1455@mmintl.UUCP> franka@mmintl.UUCP (Frank Adams) writes:
>This bothers me somewhat too.  I do have a suggestion for how to deal with
>it: have a "multi-assignment" operator.  Supposing that "$" is being used
>for this operator, then to set both "a" and "b" to zero, one would write
>"a $ b = 0", rather than "a = b = 0", as C does.

This bothers me somewhat (where have I heard this before?) -- your "$"
operator is actually instructing ANOTHER operator to have an attribute
it doesn't usually have (at least in your proposed implementation). 
In other words, in "b = 0", the "=" operation would NOT return a value,
but in "a $ b = 0", the "=" operation WOULD return a value, due only to
context, which I thought was what you were trying to avoid in the first
place.

The solution (if a solution is really necessary, and I don't think one
is) would be to change the place in your example where a special
operator is needed.  In this case, "$" would be a special type of
assignment operator: one that returned a value.  Your example would be
"a = b $ 0", indicating that the assignment of 0 to b should return a
value, which can then be assigned to a.  The plain old "=" would never
return a value, and whatever lint-like thingy you run over your
program will be perfectly happy.
-- 
Larry Wake                   uucp:   {ihnp4 | hplabs | psivax}!csun!lkw
CSUN Computer Center         BITNET: RETPLKW@CALSTATE
Northridge, CA 91330         ARPA:   RETPLKW%CALSTATE@WISCVM.WISC.EDU
"He's no fun, he fell right over."

kwh@bentley.UUCP (KW Heuer) (05/16/86)

In article <1455@mmintl.UUCP> franka@mmintl.UUCP (Frank Adams) writes:
>... Supposing that "$" is being used for this ["multi-assignment"] operator,
>then to set both "a" and "b" to zero, one would write "a $ b = 0", rather
>than "a = b = 0", as C does....  

Some dialects of BASIC use "LET A,B = 0" for this.

>On the other hand, if your language supports argument passing by address,
>it permits an output argument to be multiply assigned; something which
>assignment-with-value does not support.

What do you mean by this?  I don't see how this operator allows you to do
anything that simple assignment doesn't.  Examples?

I was going to suggest a valueless assignment operator ":=" (a := b = 0),
but now I think your idea is a little closer to what I wanted.  Instead of
"a $ b = 0" , let's write that symmetrically as
	a := }
	     } 0
	b := }
or (since R-to-L assignment is a historical wart)
	  { =: a
	0 {
	  { =: b
Now, to put that into a form that can be parsed,
	0 fork { =: a | =: b }
The advantage over "$" is that this allows the duplicated value to be used
in other contexts, like the C idiom "while ((c = getchar()) != EOF)".

The observant observer has noticed that what I have is quite close to the
FORTH syntax "0 dup a ! b !" ("!" is the store operator), except that I've
been explicit about the parallelism.

Btw (somebody is bound to point this out, may as well be me), the result of
"a = b = x" in C is not really "b = x; a = x" as implicitly assumed above;
it's "b = x; a = b".  (It makes a difference if a and b differ in width.)

Karl W. Z. Heuer (ihnp4!bentley!kwh), The Walking Lint

greg@utcsri.UUCP (Gregory Smith) (05/18/86)

In article <825@bentley.UUCP> kwh@bentley.UUCP (KW Heuer) writes:
>In article <1455@mmintl.UUCP> franka@mmintl.UUCP (Frank Adams) writes:
>>... Supposing that "$" is being used for this ["multi-assignment"] operator,
>>then to set both "a" and "b" to zero, one would write "a $ b = 0", rather
>>than "a = b = 0", as C does....  
>
>>On the other hand, if your language supports argument passing by address,
>>it permits an output argument to be multiply assigned; something which
>>assignment-with-value does not support.
>
>What do you mean by this?  I don't see how this operator allows you to do
>anything that simple assignment doesn't.  Examples?

I think he means:
	procedure proc( var a : integer );
	begin
		a:= 0;
	end;
begin
	proc( cc $ dd );	{ set cc and dd to 0 }

I cannot agree with this - this is glorifying side-effects to a bizarre
extent. The implementation is not straightforward, either. Besides, what
if 'proc' looks at 'a' before using it?

>Btw (somebody is bound to point this out, may as well be me), the result of
>"a = b = x" in C is not really "b = x; a = x" as implicitly assumed above;
>it's "b = x; a = b".  (It makes a difference if a and b differ in width.)

Right. It's sometimes not better, either, if 'x' is easier to 'get' than
'b':
------- mung.c -----
main(){
	int a,b;
	a=0 ; b=0;
	a=b=0;
}
------  some of mung.a68 ----
	clrl	a6@(-4)		; a=0 (2 words )
	clrl	a6@(-8)		; b=0
	clrl	a6@(-8)		; b=0
	movl	a6@(-8),a6@(-4)	; a=b ( 3 words)

Of course, one can always say that the compiler should have fixed that :-).

-- 
"We demand rigidly defined areas of doubt and uncertainty!" - Vroomfondel
----------------------------------------------------------------------
Greg Smith     University of Toronto      UUCP: ..utzoo!utcsri!greg

franka@mmintl.UUCP (Frank Adams) (05/21/86)

In article <825@bentley.UUCP> kwh@bentley.UUCP writes:
>In article <1455@mmintl.UUCP> franka@mmintl.UUCP (Frank Adams) writes:
>>... Supposing that "$" is being used for this ["multi-assignment"] operator,
>>then to set both "a" and "b" to zero, one would write "a $ b = 0", rather
>>than "a = b = 0", as C does....  
>>On the other hand, if your language supports argument passing by address,
>>it permits an output argument to be multiply assigned; something which
>>assignment-with-value does not support.
>
>What do you mean by this?  I don't see how this operator allows you to do
>anything that simple assignment doesn't.  Examples?

Well, in C it doesn't, since C supports call by value only.  In PL/I, for
example, one could write a procedure (called, say, getlin) which would read
a line from a file; it has four parameters -- a file, a buffer, the length
of that buffer, and the number of characters read.  With a "$" operator, one
could then write something like "getlin(fp, buff, buflen, actlen$lenread);";
without it, one must use a separate assignment.

Frank Adams                           ihnp4!philabs!pwa-b!mmintl!franka
Multimate International    52 Oakland Ave North    E. Hartford, CT 06108

jc@cdx39.UUCP (John Chambers) (05/23/86)

[Let's try again and see if readnews can acces the news files this time around.]

> > > then to set both "a" and "b" to zero, one would write "a $ b = 0", 
> > > rather than "a = b = 0", as C does....  

I've always sorta wondered why programming languages never 
seem to use the same sort of comma-based syntax that most
human languages use, e.g.:
	(a, b, c)   = 0;	/* C , PL/I*/
	(a, b, c)  := 0;	/* Pascal */
	SET a, b, c = 0 	/* Basic */
	A, B, C   = 0.0		/* Fortran */
I mean, we're all familiar with this sort of usage from
many years of using it.  In C, it almost made it into
the language, since there is a comma operator.  You just
can't use it in an "lvalue" expression.

Surely there is no problem making a compiler understand
such syntax.  As for why you might want it in C, haven't
you ever been bitten by the "feature" of incompatible 
types in a set-several-things-to-zero command?  Try the
following:
	main() {
		char  *x;
		double y;
		y = x = 0;
	}
and see what your C compiler does.  Silly, isn't it?

(Despite the Cobol fiasco, there are ideas from 
natural languages that could be carried over to 
programming languages. :-)


-- 
	John M Chambers (617-364-2000x7304)

	      / cthulhu	 \	     /usenet
	     /  inmet	  \	    / news
	...!{   harvax	   }!cdx39!{  jc
	     \  mit-eddie /	    \ uucp
	      \ mot[bos] /	     \root

greg@utcsri.UUCP (Gregory Smith) (05/26/86)

In article <201@cdx39.UUCP> jc@cdx39.UUCP (John Chambers) writes:
>Surely there is no problem making a compiler understand
>such syntax.  As for why you might want it in C, haven't
>you ever been bitten by the "feature" of incompatible 
>types in a set-several-things-to-zero command?  Try the
>following:
>	main() {
>		char  *x;
>		double y;
>		y = x = 0;
>	}
>and see what your C compiler does.  Silly, isn't it?
>
It becomes the same as
	x = 0;
	y = x;	/* actually y=(double)x */

Are you suggesting that given (x,y)=0; it will be easier for a compiler
to detect the incompatibility and generate
	x = 0;
	y = 0.0;	????
I don't really think so. Note that the written-out 'explicit' version of your
initialization is as above; y = 0 causes an implicit ( compile-time )
conversion. So writing x=y=0; is asking for trouble, anyway. Actually,
this is the case with most compilers regardless of the types of x and y,
although it shouldn't be. Changing the syntax of multiple assignments
has little bearing on the problem itself, which is one of code generation.

-- 
"We demand rigidly defined areas of doubt and uncertainty!" - Vroomfondel
----------------------------------------------------------------------
Greg Smith     University of Toronto      UUCP: ..utzoo!utcsri!greg

franka@mmintl.UUCP (Frank Adams) (05/29/86)

In article <2788@utcsri.UUCP> greg@utcsri.UUCP (Gregory Smith) writes:
>I think he means:
>	procedure proc( var a : integer );
>	begin
>		a:= 0;
>	end;
>begin
>	proc( cc $ dd );	{ set cc and dd to 0 }
>
>I cannot agree with this - this is glorifying side-effects to a bizarre
>extent. The implementation is not straightforward, either. Besides, what
>if 'proc' looks at 'a' before using it?

This would be used in a language where parameters are declared as in, out,
or inout.  The $ operator would only be legal for an out parameter.

The implementation would be for the calling program to make the additional
assignment.

Frank Adams                           ihnp4!philabs!pwa-b!mmintl!franka
Multimate International    52 Oakland Ave North    E. Hartford, CT 06108

franka@mmintl.UUCP (Frank Adams) (05/30/86)

In article <2846@utcsri.UUCP> greg@utcsri.UUCP (Gregory Smith) writes:
>It becomes the same as
>	x = 0;
>	y = x;	/* actually y=(double)x */
>
>Are you suggesting that given (x,y)=0; it will be easier for a compiler
>to detect the incompatibility and generate
>	x = 0;
>	y = 0.0;	????
>I don't really think so.

Yes, because "(x,y)=0;" is equivalent to "x=0; y=0;", unlike "x=y=0", which
as you note is equivalent to "y=0; x=y;".

On the flip side, a naive compiler will generate less efficient code for
something like:

   int i, j;
   float a;
   (i,j)=a;

than it would when the last line is "i=j=a"; it will do the float to int
conversion twice.

Frank Adams                           ihnp4!philabs!pwa-b!mmintl!franka
Multimate International    52 Oakland Ave North    E. Hartford, CT 06108

greg@utcsri.UUCP (Gregory Smith) (06/01/86)

In article <1516@mmintl.UUCP> franka@mmintl.UUCP (Frank Adams) writes:
>In article <2846@utcsri.UUCP> greg@utcsri.UUCP (Gregory Smith) writes:
>>It becomes the same as
>>	x = 0;
>>	y = x;	/* actually y=(double)x */
>>
>>Are you suggesting that given (x,y)=0; it will be easier for a compiler
>>to detect the incompatibility and generate
>>	x = 0;
>>	y = 0.0;	????
>>I don't really think so.
>
>Yes, because "(x,y)=0;" is equivalent to "x=0; y=0;", unlike "x=y=0", which
>as you note is equivalent to "y=0; x=y;".

'Equivalent' in both cases meaning 'yielding the same result' and not nec.
'implemented as'. ( I'm sure you meant that too ).

>
>On the flip side, a naive compiler will generate less efficient code for
>something like:
>
>   int i, j;
>   float a;
>   (i,j)=a;
>
>than it would when the last line is "i=j=a"; it will do the float to int
>conversion twice.

It would screw up  because it would compile i=a;j=a;. But what about
(i,j) =array[ func(foo-bar)+i]*17? If a compiler treated *that* as two
statements, it would be more than just naive.
So the code generator would have to take a look at the RHS to see if
splitting the assignment in two is a good idea or not.  My point is
that the same decision can be made with the C format of i=j=...
So the problem is not inherent in 'i=j=' - the problem is that few
( if any ) compilers go to this trouble.
I will admit that the semantics of i=j= can get funny when i and j are of
different types -especially when j is fewer bits than j.
>
>Frank Adams                           ihnp4!philabs!pwa-b!mmintl!franka



-- 
"We demand rigidly defined areas of doubt and uncertainty!" - Vroomfondel
----------------------------------------------------------------------
Greg Smith     University of Toronto      UUCP: ..utzoo!utcsri!greg