[net.lang.c] WITH statement

chris@umcp-cs.UUCP (07/12/86)

In article <1003@zog.cs.cmu.edu> dlc@zog.cs.cmu.edu (Daryl Clevenger) writes:
>   I dislike Pascal as much as the next C hacker, but one feature
>that could be useful to add to C is something akin to the Pascal
>"WITH" statement. ... By using such a construct, one avoids long
>statements when using deeply nested structures/unions or the kludgy
>method of using defines.

I never did like `with'.  I would like it a lot more if . . . well,
let me see if I can construct a good bad example first.

	type
		x = record ... end;
		y = record ... end;
		z = record ... end;

	var
		foo : x;
		zarog : y;
		prullo : z;

	{ several hundred pages of code }

		with foo, zarog, prullo do begin
			...
			{ next three statments use fields }
			snert := 5 * bazzi;
			bibble := 10;
			roj := klewp mod snert;
			...
		end;
		...

To which variables do those fields refer?

If `with' is intended as shorthand, I would like to see it used
in more this way:

		with a = foo, b = zarog, c = prullo do begin
			...
			b.snert = 5 * a.bazzi;
			c.bibble := 10;
			a.roj := c.klewp mod b.snert;

Note that this allows member name `collisions' to be disambiguated:

			b.snert = 5 * a.bazzi;
			c.bibble := 10;
			a.roj = c.klewp mod a.snert;

---if that is in fact what is meant.

(I have a feeling that `WITH' originally meant `Listen, compiler,
put a pointer to this here record into a machine register now,
because I am about to use it a whole bunch.')
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 1516)
UUCP:	seismo!umcp-cs!chris
CSNet:	chris@umcp-cs		ARPA:	chris@mimsy.umd.edu

zben@umd5.umd.edu.UUCP (07/17/86)

In article <2366@umcp-cs.UUCP> chris@maryland.UUCP (Chris Torek) writes:
> (I have a feeling that `WITH' originally meant `Listen, compiler,
> put a pointer to this here record into a machine register now,
> because I am about to use it a whole bunch.')

And well it might, if the subject record be selected from a record array.
The Pascal compiler on the SperrySaur has a limit of something like five
of these "nontrivial WITHs" to be open at any one time.

The idea was to avoid repeating the same selector expression over and over
again, and is akin to the C syntax:

       maskarray[selector] |= xbit;     /* Set X bit in maskarray */

The ambiguous condition scares me too, and I think I could live much better
with being able to take the address of the thing and then using it, like:

       recpointer := &recarray[selector];
       ...
       recpointer^.foo := 1;
       recpointer^.bar := 2;

While the & operator (find address) is highly non-standard Pascal, you can
do much the same thing in legal C right now.  Why mess with the language?

Not only has UMD5 arisen as a MicroVax from its previous incarnation as an 
11/44, but I am using a Macintosh Plus and MacKermit to type this in.
Are we having fun yet?

-- 
                    umd5.UUCP    <= {seismo!umcp-cs,ihnp4!rlgvax}!cvl!umd5!zben
Ben Cranston zben @ umd2.UMD.EDU    Kingdom of Merryland Sperrows 1100/92
                    umd2.BITNET     "via HASP with RSCS"

rcd@nbires.UUCP (07/21/86)

> The ambiguous condition scares me too, and I think I could live
> much better with being able to take the address of the thing
> and then using it, like:
> 
>        recpointer := &recarray[selector];
>        ...
>        recpointer^.foo := 1;
>        recpointer^.bar := 2;

I don't intend to flame, but there's a funny ring to this sort of view of
the (Pascal) `with' statement.  C programmers roundly criticize Pascal as
being more cumbersome in notation.  I generally agree; Pascal could allow
more terse expression without suffering...but then why is it scary when
Pascal has a construct which allows more terse expression than C?

First off, the standard disclaimer:  the `with' statement can be abused, as
can any statement (including the null statement!) in any language.

The `with' statement is an interesting construct from a programming
language standpoint; I don't know of too many others in its class.  One way
to think of it is as a procedure:
	with p^, q[i] do...
is like starting a procedure right there with (value) parameters being the
records given.  Within the procedure you have access to these objects which
is more convenient and presumably more efficient.  It's a funny open-code
sort of thing.

Opening a with using two records of the same type is possible, but rare
because it's kind of silly.  (It has nowhere near the potential for screwup
of, say, calling a procedure with two pointer parameters pointing to the
same object.)

The "scary" part of the `with' statement--the loss of qualifier in front of
field selectors--is no problem at all in practice because `with' statements
tend to be intensive activity on the records being manipulated.  I've
observed that `with' statements tend to be either fairly short (probably
under 10 lines) or the entirety of a procedure where the `with' opens one
or more of the procedure's parameters--for example:
	procedure xxx(p: pwhatzy);
	...decls
	begin with p^ do begin
	...work on the object referenced by p
	end end;

I've written a lot of Pascal and a lot more C.  Mostly I find C faster to
write, but when I start writing a sequence of code to fill in a structure,
I sure miss the `with' statement.
-- 
Dick Dunn	{hao,ucbvax,allegra}!nbires!rcd		(303)444-5710 x3086
   ...At last it's the real thing...or close enough to pretend.

rbj@icst-cmr.ARPA (Root Boy Jim) (07/21/86)

Re: WITH statement:
	The ambiguous condition scares me too, and I think I could live
	much better with being able to take the address of the thing
	and then using it, like:

	       recpointer := &recarray[selector];
	       ...
	       recpointer^.foo := 1;
	       recpointer^.bar := 2;

The ambiguity is worse than you might think. I happen to think that
all structure members that are logically the same thing ought to
have the same name. This was not allowed in original C because
structures shared the same name space. On the other hand, you could
use any structure member with any structure type.

I am glad I learned C after the change. Requiring different names
for the same item is another example where C outgrew Pascal.
	
	Not only has UMD5 arisen as a MicroVax from its previous
	incarnation as an 11/44, but I am using a Macintosh Plus and
	MacKermit to type this in.

Congrats.

	Are we having fun yet?
	
Yow!

	umd5.UUCP    <= {seismo!umcp-cs,ihnp4!rlgvax}!cvl!umd5!zben
	Ben Cranston zben@umd2.UMD.EDU    Kingdom of Merryland Sperrows 1100/92
	                  umd2.BITNET     "via HASP with RSCS"

I still see you don't believe in TABS.

	(Root Boy) Jim Cottrell		<rbj@icst-cmr.arpa>
Hello...  IRON CURTAIN?  Send over a SAUSAGE PIZZA! World War III?  No thanks!

rbj@icst-cmr (Root Boy Jim) (07/22/86)

	> The ambiguous condition scares me too, and I think I could live
	> much better with being able to take the address of the thing
	> and then using it, like:
	> 
	>        recpointer := &recarray[selector];
	>        ...
	>        recpointer^.foo := 1;
	>        recpointer^.bar := 2;
	
	I don't intend to flame, but there's a funny ring to this sort
	of view of the (Pascal) `with' statement.  C programmers
	roundly criticize Pascal as being more cumbersome in notation.
	I generally agree; Pascal could allow more terse expression
	without suffering...but then why is it scary when Pascal has a
	construct which allows more terse expression than C?

There's a fear down here we can't forget, hasn't got a name just yet.
Because the association is not explicit. I suppose if two records
had the same member name you would get a complaint, but changing
the names later would leave you no indication of what the code meant.

	First off, the standard disclaimer:  the `with' statement can
	be abused, as can any statement (including the null statement!)
	in any language.

I agree, I'm not picking this nit.

	The `with' statement is an interesting construct from a
	programming language standpoint;
	
I agree. It's a good idea, but a bad implementation. Saving two
chars isn't too Wirthwhile (moan), a better way might have been:
`with pointer^array[index]^ as p, quitelong[i] as q do ...

	I don't know of too many
	others in its class.  One way to think of it is as a
	procedure:
		with p^, q[i] do...
	is like starting a procedure right there with (value)
	parameters being the records given.  Within the procedure you
	have access to these objects which is more convenient and
	presumably more efficient.  It's a funny open-code sort of
	thing.

	Opening a with using two records of the same type is possible,
	but rare because it's kind of silly. 

Why do you say that? Consider copying or comparing two records. And
how do the member names know which pointer to use? And if you use
different record types, what if the members have the same names?
Is this even legal? 

	(It has nowhere near the potential for screwup of, say, calling
	a procedure with two pointer parameters pointing to the same object.)

That might be what you want to do.

	The "scary" part of the `with' statement--the loss of qualifier
	in front of field selectors--is no problem at all in practice
	because `with' statements tend to be intensive activity on the
	records being manipulated.  I've observed that `with'
	statements tend to be either fairly short (probably under 10
	lines) or the entirety of a procedure where the `with' opens
	one or more of the procedure's parameters--for example:
		procedure xxx(p: pwhatzy);
		...decls
		begin with p^ do begin
		...work on the object referenced by p
		end end;

I agree here too. Almost anything is OK, as long as it is localized.
	
	I've written a lot of Pascal and a lot more C.  Mostly I find C
	faster to write, but when I start writing a sequence of code to
	fill in a structure, I sure miss the `with' statement.  --

You have it, either symbolically via #define p pointer->array[index]
or by assigning pointer->array[index] to a (possibly register) variable p.

I guess the thing that bothers me most about Pascal is that it's a half
assed job, whipped up to teach a few good ideas, without giving thought
to completeness or applicability to complex tasks. Its author then
abandoned it and went on to design other languages which he also
then abandoned instead of fixing his mistakes. 

	Dick Dunn    {hao,ucbvax,allegra}!nbires!rcd	(303)444-5710 x3086

(Root Boy) Jim Cottrell		<rbj@icst-cmr.arpa>

	...At last it's the real thing...or close enough to pretend.
	
It's even worse than it appears...

daveh@cbmvax.cbm.UUCP (Dave Haynie) (07/22/86)

> Summary: no danger--it's like a procedure
>
> The "scary" part of the `with' statement--the loss of qualifier in front of
> field selectors--is no problem at all in practice because `with' statements
> tend to be intensive activity on the records being manipulated.  I've
> observed that `with' statements tend to be either fairly short (probably
> under 10 lines) or the entirety of a procedure where the `with' opens one
> or more of the procedure's parameters--for example:
>       procedure xxx(p: pwhatzy);
>       ...decls
>       begin with p^ do begin
>       ...work on the object referenced by p
>       end end;
>
> I've written a lot of Pascal and a lot more C.  Mostly I find C faster to
> write, but when I start writing a sequence of code to fill in a structure,
> I sure miss the `with' statement.
> --
> Dick Dunn     {hao,ucbvax,allegra}!nbires!rcd         (303)444-5710 x3086
>    ...At last it's the real thing...or close enough to pretend.

Ideally.  Though I had a job one time translation large chunks of Pascal
code to C.  This was on a large CAD project, in other words, a big, non
trivial, etc. example of Pascal.  There were sections of the Pascal
code with 5-10 levels of nested WITH statements.  You get identifiers
flying around all over the place, with no concept as to which structures
they belong to (at least, not without referring to about six pages of
RECORD declarations to track them down). Its may be very nice to
have the WITH construct available when writing code, but its main purpose
when maintaining or translating code is to create confusion and obstruct
the real purpose of the code you're examining.  It could lead to more
efficient code when used properly, though I wonder if anyone thinks of
the troubles involved when using it on a large sca be believed!
   The reviewer now moves to the traitorous character who wishes to leave
his beloved homeland. It is so sad that his activities are praised and
held up to be admired by the reader. Why everybody knows that EVERYBODY
has a job, a place to live, and no charge education and medical care. Who
would believe that it's illegal to live in any city, Especially MOSCOW, without
permission. And to get permission to live in any city, you must work there.
But to get a job, you must have permission to live in the city. See? And the
references to the Soviet Submarine forces are despicable. The observation
that all soviet submariners are bald from the radiation is patently false...
they just like to shave their heads after military service as a sign to their
comrades : a badge of honor and self sacrifice.
This book tries to give the impression that Russians are a besotted,
hopeless bunch of victims of their leaders and the Communist Party!
The descriptive scenes of medical care are fabrications

rbj@icst-cmr (Root Boy Jim) (07/23/86)

	Ideally.  Though I had a job one time translation large chunks
	of Pascal code to C.  This was on a large CAD project, in other
	words, a big, non trivial, etc. example of Pascal.  There were
	sections of the Pascal code with 5-10 levels of nested WITH
	statements.  You get identifiers flying around all over the
	place, with no concept as to which structures they belong to
	(at least, not without referring to about six pages of RECORD
	declarations to track them down). Its may be very nice to have
	the WITH construct available when writing code, but its main
	purpose when maintaining or translating code is to create
	confusion and obstruct the real purpose of the code you're
	examining.  It could lead to more efficient code when used
	properly, though I wonder if anyone thinks of the troubles
	involved when using it on a large sca be believed!

While I'm no lover of Pascal, I CAN offer a porting solution. But
first you must answer one question: Would you be happier (I didn't
say `happy', I said `happi-ER') porting the code without the WITH's?
You would? Good! Here's how.

First you need the original Pascal compiler. Then you change all the
`WITH p^'s to `WITH xp^'s, that is bogusize the WITH, but preserve
the original name. Then fix all the errors by prepending `p^' where
necessary, and remove the with statement. Yow!

Now you are ready for all the other headaches.

	(Root Boy) Jim Cottrell		<rbj@icst-cmr.arpa>
This ASEXUAL PIG really BOILS my BLOOD...He's so..so.....URGENT!!