🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Thread View: net.lang.pascal
5 messages
5 total messages Started by idc Wed, 06 Aug 1986 10:31
Linear search again
#322
Author: idc
Date: Wed, 06 Aug 1986 10:31
57 lines
2151 bytes
A small contribution to the debate re. forced termination of linear search
in Pascal.  Below is a little program in ISO level 1 Pascal that
illustrates the method.  It is not original; for example see the paper

R.G. Dromey, "Forced termination of loops", Softw.pract.exp., pp 29-40,
Vol. 15 No. 1, January 1985.

which I strongly recommend.  It has only two disadvantages over the
state indicators method: (i) The index variable cannot have the same
subrange as the indextype of the array (but that is not possible with
conformant array parameters anyway), and (ii) really the same as (i),
-maxint may not be the lower bound (in general pred(lowerbound) must be
defined.  N.B. Neither a goto nor a Boolean in sight!  Read the ref. for
full details.
Here is the example dressed up as a "find a character in a string" function.
------------

program ForcedTerminationTest(Output);




function find(ch:Char; string: packed array[lo..hi:Integer] of Char):Integer;
{
*  pre: lo > -maxint
* post: if find(ch,string) = -maxint then true else string[find(ch,string)]=ch
}
 var
	i, N: Integer;
begin
	{ -- Initialise loop variables }
	i := lo-1;  N := hi;
	{ -- Linear search with possible forced termination on hit }
	while i <> N do
	   if string[i+1]=ch then N := i else i := i+1;
	{ -- Test termination state }
	if i <> hi then find := i+1 else find := -maxint
end{ find};




begin

{ -- Test cases }
writeln(Output,
	find('!', 'Forced termination is a good thing!'):1,
	' ',
	find('?', 'There is no question mark in this string')
       )
 
end.
----------


ps. am really ian@ux.cs.man.ac.uk but am experiencing trouble posting from there.
Re: Linear search again
#324
Author: Chris Torek
Date: Thu, 07 Aug 1986 21:54
67 lines
2864 bytes
In article <871@minster.UUCP> idc@minster.UUCP (idc) writes:
>Below is a little program in ISO level 1 Pascal that
>illustrates [a] method [of forced termination of linear search].
>
>Here is the example dressed up as a "find a character in a string" function.
>
>function find(ch:Char; string: packed array[lo..hi:Integer] of Char):Integer;
>{
>*  pre: lo > -maxint
>* post: if find(ch,string) = -maxint then true else string[find(ch,string)]=ch
>}
> var
>	i, N: Integer;
>begin
>	{ -- Initialise loop variables }
>	i := lo-1;  N := hi;
>	{ -- Linear search with possible forced termination on hit }
>	while i <> N do
>	   if string[i+1]=ch then N := i else i := i+1;
>	{ -- Test termination state }
>	if i <> hi then find := i+1 else find := -maxint
>end{ find};

Actually, I am not entirely satisified with any of these notations.
If I were instructing a person to find an object, I might say
something like `search starting at low and going forward, until
either you find it or you get to hi'; so in a computer language,
I might prefer, e.g.:

	{ return the position of the specified character in the given
	  string, or -maxint if not found }
	function find(ch: char; string: packed array[l..h: integer] of char):
		integer;
	var
		i, answer: integer;
	begin
		{ assume it will not be found }
		answer := -maxint;
		{ iterate only until it is found }
		for i in [l..h] until answer <> -maxint do
			if string[i] = ch then answer := i
		end for;
		find := answer
	end;

This puts the termination condition directly in the `for' loop.

I think (I am at home or I would check) that the language Mesa,
developed by Xerox, has a loop of this form (indeed, the loop can
declare `i' as well, just for the duration of the loop itself,
which is also appropriate)---though in Mesa one would be more
likely to write

	-- apologies for syntax; it has been a while

	find: PROC [ch: CHAR, string: LONG STRING]
		RETURNS [pos: CARDINAL, found: BOOL];
	BEGIN
	    FOR i:CARDINAL in [0..String.Length[string]] DO
		IF string[i] = ch THEN RETURN [i, TRUE];
	    ENDLOOP;
	    RETURN [0, FALSE];
	END;
-- 
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
Multiple loop exits (was linear search revisited)
#323
Author: Arthur M. Keller
Date: Fri, 08 Aug 1986 09:40
56 lines
2490 bytes
First, let me say that I am opposed to unrestricted use of GOTOs.
However, I do like the ability to prematurely exit from a construct.
The argument that premature exits from constructs (FOR loops,
functions, etc.) represent multiple exits from the construct is
misguided.  There is only one exit from the construct.  There are
merely multiple ways of getting there.  Having an explicit exit
in a construct is often better than implicitly falling through to
the bottom.

Consider the following way of writing the linear search using invented syntax:

found := false;
FOR "search foo" index := low TO high DO
	IF foo[index]=key
	    THEN location := index;
		EXIT "search foo";
		ENDIF;
ENDFOR "search foo";

Semantics of naming BEGINs and ENDs:
A loop may be named at either the BEGIN or the END.  Both will name the
block.  If both are present, they must match exactly.

Semantics of the EXIT construct:
EXIT causes execution to continue at the end of the named BEGIN-END block
if a name is specified, or at the end of the innermost BEGIN-END block
if no name is specified.

To implement the semantics of CONTINUE using the EXIT construct:

FOR "outer" ....
    BEGIN "inner"
	EXIT "inner"; (* means CONTINUE with the next iteration of the loop *)
	EXIT "outer"; (* means leave the FOR loop altogether *)
    END "inner";
ENDFOR "outer";

An EXIT is particularly helpful for thinking like:

you know you're done when
	abcdfefgtgf
  or   ajsadjdfjaldjla
  or   asdasdsadsadasd

Once you make any of these true, you can exit.

An EXIT is also helpful for handling exceptions and errors without
unnecessarily cluttering up code to ensure than nothing is done
in the event of an error.

Arthur
-- 
------------------------------------------------------------------------------
Arpanet: ARK@SALLY.UTEXAS.EDU
UUCP:    {gatech,harvard,ihnp4,pyramid,seismo}!ut-sally!ark
Re: Linear search again
#325
Author: Ben Cranston
Date: Sat, 09 Aug 1986 00:56
20 lines
1492 bytes
In article <2785@umcp-cs.UUCP> chris@maryland.UUCP (Chris Torek) writes:

>	find: PROC [ch: CHAR, string: LONG STRING]
>		RETURNS [pos: CARDINAL, found: BOOL];
>	BEGIN
>	    FOR i:CARDINAL in [0..String.Length[string]] DO
>		IF string[i] = ch THEN RETURN [i, TRUE];
>	    ENDLOOP;
>	    RETURN [0, FALSE];
>	END;

I always avoided these nonstandard returns because they make it painful to
drop in debug print statements.  I would always slap in WRITELN(MYARGS) at
the top, and WRITELN('Returning from FIND') at the bottom, and wonder why
I never saw the 'Returning from FIND' output...  If you are trying to find
an infinite loop this can be really misleading.
-- 
                    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"
Re: debug prints (was Re: Linear search again)
#326
Author: Chris Torek
Date: Sat, 09 Aug 1986 01:17
39 lines
2206 bytes
>In article <2785@umcp-cs.UUCP> I wrote:
[an example of how a Mesa programmer would probably write `find']:
>>	find: PROC [ch: CHAR, string: LONG STRING]
>>		RETURNS [pos: CARDINAL, found: BOOL];
>>	BEGIN
>>	    FOR i:CARDINAL in [0..String.Length[string]] DO
>>		IF string[i] = ch THEN RETURN [i, TRUE];
>>	    ENDLOOP;
>>	    RETURN [0, FALSE];
>>	END;

In article <1174@umd5> zben@umd5.umd.edu (Ben Cranston) writes:
>I always avoided these nonstandard returns because they make it painful to
>drop in debug print statements.  I would always slap in WRITELN(MYARGS) at
>the top, and WRITELN('Returning from FIND') at the bottom, and wonder why
>I never saw the 'Returning from FIND' output...  If you are trying to find
>an infinite loop this can be really misleading.

Ah, but in Mesa, no one ever seems to use debug prints: for there is
a very complete debugger that is always accessible.  For that matter,
if you did wish to wrap `find' with debug print statements, you could
simply rename the procedure to `findInternal' and add

	-- Again, details may be wrong; all the manuals are four miles
	-- away.
	find: PROC [ch: CHAR, string: LONG STRING]
		RETURNS [pos: CARDINAL, found: BOOL];
	BEGIN
	    Msg.PutMsg["Enter find"L];
	    [pos, found] _ internalFind[ch, string];--`_' represents left-arrow
	    Msg.PutMsg["Exit find"L];
	    RETURN [pos, found];
	END;

Indeed, this technique works in every language.
-- 
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
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