🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Thread View: comp.lang.oberon
6 messages
6 total messages Started by Peter Froehlich Sat, 30 Mar 1996 22:47
The Trouble with WITH...
#1243
Author: Peter Froehlich
Date: Sat, 30 Mar 1996 22:47
54 lines
2389 bytes
Hi there!

   Regarding  the  "theoretical"  problems  of  the WITH statement I humbly
request  a  clarification  from  someone with a better understanding of the
problem.  Here is what Oakwood says:

----- CUT -----
WITH and guarded variables

It  is  possible  to alter a guarded pointer variable within the scope of a
guarding WITH statement, example:

	TYPE
	  T  = RECORD END;     P  = POINTER TO T;
	  T1 = RECORD (T) END; P1 = POINTER TO T1;
	  T2 = RECORD (T) END; P2 = POINTER TO T2;
	PROCEDURE X;
	  VAR p: P; p1: P1; p2: P2;
	  PROCEDURE Y; 
	  BEGIN 
	    p := p2
	  END Y;
	BEGIN
	  NEW (p); NEW(p1); NEW(p2); p := p1;
	  WITH p: P1 DO
	    Y  (*p is now of type P2 and not P1*)
	  END
	END X;

A practical way to handle this is:

If  the  compiler  can be sure it is safe then give no warning message.  If
there  can  be  any  doubt then do give a warning message.  A sophisticated
compiler  could  automatically  insert  the  additional relevant type guard
checks.
----- CUT -----

   The way I see it, the real problem is whether the WITH statement applies
"statically"  ie.   only  to the text contained within or "dynamically" ie.
on the whole control flow initiated from within:

   - Using a "static WITH" the problem is present since the static type of
     p within Y() is P.  So the assignment of p2 to p is legal.

   - Using a "dynamic WITH" the problem disappears (IMHO) because the WITH
     would temporarily alter the static type of p to be P1, making the
     assignment in Y() illegal.  Of course, this can only be enforced at
     run-time.

Please  clear  up  my confusion (or tell me that I have properly understood
the problem).
                  _
By(T)e...   /| _ //3000 /\ People who use Pascal for serious programming |\
   Peter... \| \X/\miga \/ fall into a fatal trap.  (Brian W. Kernighan) |/
Re: The Trouble with WITH...
#1256
Author: M Hamburg
Date: Tue, 02 Apr 1996 16:57
9 lines
904 bytes
Another solution is to say that WITH p: T introduces a new variable named
p within the scope of the WITH statement that is distinct from the
variable of the same name in the containing scope. The variable created
within the WITH cannot be assigned to. Since assigning to a WITH'd
variable is generally bad form anyway, this definition doesn't cause a
problem for "well formed" programs, and it is safe for "ill formed"
programs.

Mark
Re: The Trouble with WITH...
#1270
Author: Brian Hawley
Date: Wed, 03 Apr 1996 23:33
43 lines
2877 bytes
In article <4jrm9b$l8m@newsbf02.news.aol.com>, mhamburg@aol.com (M Hamburg) wrote:
>Another solution is to say that WITH p: T introduces a new variable named
>p within the scope of the WITH statement that is distinct from the
>variable of the same name in the containing scope. The variable created
>within the WITH cannot be assigned to. Since assigning to a WITH'd
>variable is generally bad form anyway, this definition doesn't cause a
>problem for "well formed" programs, and it is safe for "ill formed"
>programs.
>
>Mark

There is a variant of this solution where you don't even need to restrict 
assignments. The only problem with WITH arises when an extended pointer 
variable is reallocated while inside the WITH block. Instead have WITH 
introduce a new pointer variable when extending the static type of pointers 
and have it behave as before in all other cases. If you have WITH use an alias 
pointer and the original pointer is reallocated or reassigned then the alias 
refers to the original record rather than the new one. The only question is 
whether changes to the value of the aliased pointer should be propagated to 
the original; if they are it could lead to some obscure bugs (in exactly the 
same places you had WITH bugs before, but safer ones), but if they aren't it 
could be quite confusing to the writer of the WITH block when their changes 
(to the pointer variable, not the referenced value) are undone after the 
block. It may not be what was originally intended but it would be safe, and 
any side effect can be well documented in the language manual. 

This would be a simple change to either OP2 or a GSA based compiler like OOC. 
You would just allocate a new variable at the beginning of the WITH block if 
the original variable is a pointer type. If you are propagating changes then 
every change to the pointer variable in the code in the WITH block would 
change both the alias and the original. No changes would be needed in other 
code. 

I think that if you propagate changes from the alias to the original then any 
existing code would run without change. Any place that you would have an alias 
bug before you would have one now, but this bug wouldn't violate type safety 
and corrupt the heap--instead you would just be referring to the old record 
instead of the new one, a bug that could be useful sometimes.

So what do you think?

Brian Hawley
bhawley@luc.edu
Re: The Trouble with WITH...
#1274
Author: Stefan Ludwig
Date: Thu, 04 Apr 1996 08:05
41 lines
2262 bytes
In article <4jv1c1$drh@artemis.it.luc.edu>,
Brian Hawley <bhawley@luc.edu> wrote:
>In article <4jrm9b$l8m@newsbf02.news.aol.com>, mhamburg@aol.com (M Hamburg) wrote:
>>Another solution is to say that WITH p: T introduces a new variable named
>>p within the scope of the WITH statement that is distinct from the
>>variable of the same name in the containing scope. The variable created
>>within the WITH cannot be assigned to. Since assigning to a WITH'd
>>variable is generally bad form anyway, this definition doesn't cause a
>>problem for "well formed" programs, and it is safe for "ill formed"
>>programs.
>>
>>Mark
>
>There is a variant of this solution where you don't even need to restrict 
>assignments. The only problem with WITH arises when an extended pointer 
>variable is reallocated while inside the WITH block. Instead have WITH 
>introduce a new pointer variable when extending the static type of pointers 
>and have it behave as before in all other cases. If you have WITH use an
...deleted...
>So what do you think?
>
>Brian Hawley
>bhawley@luc.edu

The solution most in the "Spirit of Oberon" would be to drop WITH on pointers
altogether.
This was suggested in Szyperski's "ETHOS" thesis and discussed at the Institute
at length. The reason we left it the way it is, was that too much System3 code
would have needed a rewrite.

I strongly advocate dropping WITH on pointers in commercial compilers.
It's a hole in the type system, and it needs to be plugged!

  Stefan H-M Ludwig              mailto:ludwig@inf.ethz.ch
                                 http://www-cs.inf.ethz.ch/~ludwig
  Institute for Computer Systems
  Swiss Federal Institute of Technology (ETH)
  CH-8092 Zurich, Switzerland

  Phone: 41-1-632 7301
  Fax  : 41-1-632 1307
Re: The Trouble with WITH...
#1301
Author: Alex Nedorya
Date: Mon, 08 Apr 1996 19:20
35 lines
1576 bytes
Stefan Ludwig wrote:
> [deleted]
> 
> The solution most in the "Spirit of Oberon" would be to drop WITH on pointers
> altogether.
> This was suggested in Szyperski's "ETHOS" thesis and discussed at the Institute
> at length. The reason we left it the way it is, was that too much System3 code
> would have needed a rewrite.
> 
> I strongly advocate dropping WITH on pointers in commercial compilers.
> It's a hole in the type system, and it needs to be plugged!

XDS Oberon-2 (starting from v2.12) reports an error if the value of pointer may be changed
inside WITH, like in 

TYPE 
  P = POINTER TO R;
  R = RECORD i: INTEGER END;
  P1 = POINTER TO R1;
  R1 = RECORD (R) n: INTEGER END;

PROCEDURE proc1(p: P);
  PROCEDURE proc2;
  BEGIN
    p:=NIL;
  END proc2;
BEGIN
  WITH p: P1 DO
    proc2;
  END;
END proc1;

I think it is better solution then dropping WITH on pointers.

-- Alex
Re: The Trouble with WITH...
#1305
Author: Stefan Ludwig
Date: Wed, 10 Apr 1996 07:46
72 lines
2268 bytes
In article <318BAE1B.443@iis.nsk.su>, Alex Nedorya  <ned@iis.nsk.su> wrote:
>Stefan Ludwig wrote:
>> I strongly advocate dropping WITH on pointers in commercial compilers.
>> It's a hole in the type system, and it needs to be plugged!
>
>XDS Oberon-2 (starting from v2.12) reports an error if the value of
>pointer may be changed inside WITH, like in 
>
>TYPE 
>  P = POINTER TO R;
>  R = RECORD i: INTEGER END;
>  P1 = POINTER TO R1;
>  R1 = RECORD (R) n: INTEGER END;
>
>PROCEDURE proc1(p: P);
>  PROCEDURE proc2;
>  BEGIN
>    p:=NIL;
>  END proc2;
>BEGIN
>  WITH p: P1 DO
>    proc2;
>  END;
>END proc1;
>
>I think it is better solution then dropping WITH on pointers.
>
>-- Alex

You cannot check this for all cases! It's not safe. Consider the following:

MODULE A;
	VAR p*: Pointer;
END A.

MODULE B;
	IMPORT A;
	PROCEDURE Change*;
	BEGIN NEW(A.p)
	END Change;
END B.

MODULE C;
	IMPORT A, B;
	...
	PROCEDURE Crash*;
	BEGIN
		WITH A.p: Extension DO
			B.Change;
			do something with A.p.extendedField ... uh oh!
		END
	END Crash;
END C.

I agree, it's a pathological case, but most of the time, it's those
pathological cases that get you!

In the example above, unless you do global system analysis, you cannot find
an inconsistency (unless you're conservative and flag everything that might
change the WITH'ed pointer). IMHO, dropping WITH on pointers is the better
solution and much more readable as well...

Regards,

  Stefan H-M Ludwig              mailto:ludwig@inf.ethz.ch
                                 http://www-cs.inf.ethz.ch/~ludwig
  Institute for Computer Systems
  Swiss Federal Institute of Technology (ETH)
  CH-8092 Zurich, Switzerland

  Phone: 41-1-632 7301
  Fax  : 41-1-632 1307
Thread Navigation

This is a paginated view of messages in the thread with full content displayed inline.

Messages are displayed in chronological order, with the original post highlighted in green.

Use pagination controls to navigate through all messages in large threads.

Back to All Threads