[net.lang.pascal] Pascal vs C, again

jack@mcvax.UUCP (07/17/86)

I'm getting sick and tired of all those people picking on pascal,
and saying "C is better", without giving *any* reason for it.

Don't get me wrong, I use C every day, and pascal (luckily) only
every other day, but pascal has one enormous advantage over C:
when I get the compiler to accept my program, it will do what I
intended in 99% of the cases.
With C, the compiler will catch 30% of the bugs, lint will catch
another 30%, and the other 40% has to be tackled using adb, 
if (debug ) printf...., and rubbish like that.

You can say a lot of things about pascal, but not that it wasn't
well-designed. And, even though you have to do very wierd things
to get some things to work, it *is* possible to write medium to
large scale programs in it, and get them to work *fast*. Anyone
interested in my SMTP mail server, and my RFC822 mailer written in
pascal in ~3 months (2 days/week)? I'm now working on it's counterpart
in C, and it isn't even *half* finished in that time, let alone
debugged.

As an aside: as soon as I can get my employers to buy Modula-2
compilers (and rewrite all existing software in that language, also),
I will happily rm /bin/cc and DELETE CMDNC0>PASCAL.SAVE. But
that wasn't what this discussion was about......
-- 
	Jack Jansen, jack@mcvax.UUCP
	The shell is my oyster.

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

In article <7014@boring.mcvax.UUCP> jack@boring.uucp (Jack Jansen) writes:
>
>I'm getting sick and tired of all those people picking on pascal,
>and saying "C is better", without giving *any* reason for it.
>
:
>You can say a lot of things about pascal, but not that it wasn't
>well-designed. And, even though you have to do very wierd things
>to get some things to work, it *is* possible to write medium to

Challenge: given

var	x: array [1..1000] of integer;

write a code fragment to find the location of the first 0 in x. The
condition that no zeroes exist must be distinguished.

Further rules:
	- Standard Jensen & Wirth Pascal ( no break from loop )
	- *** x[i] must not be evaluated for i<1 or i>1000 ***
	- The search loop must be terminated as soon as a zero is found.
	- 'a or b', 'a and b' always evaluate both a and b ( I think
	   this is a rule in Jensen & Wirth )

This is the best I can find:
	var i: integer;
	...
	i :=1 ;
	while i<1000 and x[i] <> 0 do
		i := i+1;
	if x[i] = 0 then writeln('zero at location', i )
	else writeln('not found');

weird,huh? Note that the condition 'x[i]=0' is evaluated twice ( once
in the negative sense ), which would be unacceptable if we were searching
an array of records and the test was expensive.

Nobody can call this a special case... and I don't think my rules are
unreasonable. The problem is the behaviour of 'and' plus the lack of 'break'.

-- 
"You'll need more than a Tylenol if you don't tell me where my father is!"
						- The Ice Pirates
----------------------------------------------------------------------
Greg Smith     University of Toronto      UUCP: ..utzoo!utcsri!greg

gaynor@topaz.RUTGERS.EDU (Silver) (07/20/86)

[ You are getting sleeepy, very sleeeeepy...  tired...  relaxed...  Your ]
[ eyelids are getting heeeaavy...  closing...  You are now in my power.  ]

In article <3130@utcsri.UUCP>, greg@utcsri.UUCP (Gregory Smith) writes:

> ....

[Begin Paraphrasing]

> Write a code fragment to ensure all the elements of x (an array [1
> .. 1000] of integer) are non-zero, in standard Pascal.  All operands
> of boolean expressions are assumed evaluated.

[End Paraphrasing]

> ....

> This is the best I can find:
> 	var i: integer;
> 	...
> 	i :=1 ;
> 	while i<1000 and x[i] <> 0 do
> 		i := i+1;
> 	if x[i] = 0 then writeln('zero at location', i )
> 	else writeln('not found');
> 
> weird,huh? Note that the condition 'x[i]=0' is evaluated twice ( once
> in the negative sense ), which would be unacceptable if we were searching
> an array of records and the test was expensive.

Your analysis of your own code is misleading.  Assuming an arbitrarily
large array and the unit of work is array element comparison, your
code is an optimal solution.  Your gripe about evaluating x[i] twice
when it is noticed that i is indexing a zero element is NOT valid,
though, because it is only a constant amount of work (q: what's the
difference between 6984713 out of 100000000 and 6948714 out of
10000000? a: practically nothing).

Of course, if the size of the array is constrained to a (small)
constant, then your gripe about your solution IS valid.  Perhaps a
better (in terms of array element comparisons) solution, using boolean
flags...

  function Any_Zeros (List : array [0 .. List_Size] of integer) : boolean;
                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
                             no flames, I know it wants a type identifier...

    var
      i : -1 .. List_Size;
      Zero_Found : boolean;

    begin
        i := -1;
        Zero_Found := false;
        while (i < List_Size) and not Zero_Found do begin
            i := succ (i);
            Zero_Found := (List[i] = 0)
          end;
        Any_Zeros := Zero_Found
      end;

Note that twice as many book-keeping (namely assignments) operations
are done, but we've assumed array element comparison as the sole unit
of work.  The order of the book-keeping operations remains of the same
order as that of the order of the unit of work.

> The problem is the behaviour of 'and' plus the lack of 'break'.

Noper.  The effect of the break statement can always be simulated by
the use of boolean flags.  These will increase the amount of the
book-keeping, but not change the order of an algorithm as far as the
fundamental work unit(s) goes.

The evaluation of the operands in boolean expressions can be
controlled with nested if-thens.  For example, if I wanted to write

    if a and b then ...

but didn't want to bother evaluating b if a was false, I would write

    if a then if b then ...

These are applications of Boehm and Jacopini's Fundamental Control
Structure Theorem.  For more information, consult a *human*
interpretation of this theorem (perhaps sections 5.2 and 5.3 of The
Programming Language Landscape, by Ledgard and Marcotty (Science
Research Associates, Inc; 1981)).

Do your homework BEFORE posting.  People are watching you, and paying
for it.

Silver  {...!topaz!gaynor}

ear@duke.UUCP (Eric A. Raymond) (07/21/86)

In article <3130@utcsri.UUCP> greg@utcsri.UUCP (Gregory Smith) writes:

>Challenge: given
>
>var	x: array [1..1000] of integer;
>
>write a code fragment to find the location of the first 0 in x. The
>condition that no zeroes exist must be distinguished.
>
>Further rules:
>	- Standard Jensen & Wirth Pascal ( no break from loop )
>	- *** x[i] must not be evaluated for i<1 or i>1000 ***
>	- The search loop must be terminated as soon as a zero is found.
>	- 'a or b', 'a and b' always evaluate both a and b ( I think
>	   this is a rule in Jensen & Wirth )
>
>This is the best I can find:
>	var i: integer;
>	...
>	i :=1 ;
>	while i<1000 and x[i] <> 0 do
>		i := i+1;
>	if x[i] = 0 then writeln('zero at location', i )
>	else writeln('not found');


Well assuming that a OR b only evaluates b if a is false, how about:

var i: integer;

i := 0;
repeat
  i := i + 1; {or use INC(i) if one exists}
until (i > 1000) OR (x[i] = 0);

if (i > 1000) then 
  writeln('No zero found')
else
  writeln('Zero at location ',i);

Note that this takes an extra loop (1001 .vs. 1000) if there is no zero.
Also, the condition that x[i>1000] not be evaluated is dependent upon
the previous assumption of OR evaluation.  Now if you didn't care whether
x[i>1000] was evaluated and if you don't mind x[i] being evaluated twice,
then you could use something like this ...

until (i = 1000) OR (x[i] =0);

if (x[i] = 0) then ... found
else ... not found


Your point (however understated it may be) that C's ability to include 
assignment in conditional tests is well taken.  An optimizing compiler
should be able to generate code similar to what C allows one to explicitly
encode.  (This would not be so if x[i] were some (expensive) function.)

-- 
Eric A. Raymond                                   UUCP: ...decvax!mcnc!duke!ear

jack@mcvax.uucp (Jack Jansen) (07/21/86)

In article <3130@utcsri.UUCP> greg@utcsri.UUCP (Gregory Smith) writes:
>
>Challenge: given
>
>var	x: array [1..1000] of integer;
>
>write a code fragment to find the location of the first 0 in x. The
>condition that no zeroes exist must be distinguished.
>...
>This is the best I can find:
>	var i: integer;
>	...
>	i :=1 ;
>	while i<1000 and x[i] <> 0 do
		     ^ Type of operands conflict :-)
>		i := i+1;
>	if x[i] = 0 then writeln('zero at location', i )
>	else writeln('not found');
>
>weird,huh? Note that the condition 'x[i]=0' is evaluated twice ( once
>in the negative sense ), which would be unacceptable if we were searching
>an array of records and the test was expensive.
>
Sigh, I shouldn't go into this, but I can't resist.

First, what you do here is take a feature that is missing from pascal,
and show a use for it. I *know* break is nice, and I *know* that it is missing
from pascal. However, I could also come up with some nice question that would
be ideally suited to use set's for, and you would have to come up with quite
an ugly solution in C.

Moreover, your statement about 'x[i]=0' being evaluated twice is not true.
Don't forget that x[i]=0 is also evaluated for every time through the loop,
so you just save one test in C....
-- 
	Jack Jansen, jack@mcvax.UUCP
	The shell is my oyster.

marty@ism780c.UUCP (Marty Smith) (07/21/86)

In article <3130@utcsri.UUCP> greg@utcsri.UUCP (Gregory Smith) writes:
>
>Challenge: given
>
>var	x: array [1..1000] of integer;
>
>write a code fragment to find the location of the first 0 in x. The
>condition that no zeroes exist must be distinguished.
>
>Further rules:
>	- Standard Jensen & Wirth Pascal ( no break from loop )
>	- *** x[i] must not be evaluated for i<1 or i>1000 ***
>	- The search loop must be terminated as soon as a zero is found.
>	- 'a or b', 'a and b' always evaluate both a and b ( I think
>	   this is a rule in Jensen & Wirth )
>
>This is the best I can find:
>	var i: integer;
>	...
>	i :=1 ;
>	while i<1000 and x[i] <> 0 do
>		i := i+1;
>	if x[i] = 0 then writeln('zero at location', i )
>	else writeln('not found');
>
>weird,huh? Note that the condition 'x[i]=0' is evaluated twice ( once
>in the negative sense ), which would be unacceptable if we were searching
>an array of records and the test was expensive.
>
What's wrong with this one?

	label 1,2;
	var i: integer;
	...
	i :=1 ;
	while i<=1000 do
		if x[i] = 0 then goto 1
		else i := i+1;

	writeln('not found');
	goto 2;
1:      writeln('zero at location', i )
2:      ...



		  Martin Smith

greg@utcsri.UUCP (Gregory Smith) (07/21/86)

In article <5378@topaz.RUTGERS.EDU> gaynor@topaz.RUTGERS.EDU (Silver) writes:
[linear array search in Pascal]
>me (greg@utcsri:)
>> weird,huh? Note that the condition 'x[i]=0' is evaluated twice ( once
>> in the negative sense ), which would be unacceptable if we were searching
>> an array of records and the test was expensive.
>
>Your analysis of your own code is misleading.  Assuming an arbitrarily
>large array and the unit of work is array element comparison, your
>code is an optimal solution.  Your gripe about evaluating x[i] twice
>when it is noticed that i is indexing a zero element is NOT valid,
>though, because it is only a constant amount of work (q: what's the
>difference between 6984713 out of 100000000 and 6948714 out of
>10000000? a: practically nothing).

True, except it is quite common for a search test to produce a 'no-match'
result very quickly most of the time, and to always take a long time to
come up with match. The 'match' is the repeated test. Your point is well taken
though.

>Of course, if the size of the array is constrained to a (small)
>constant, then your gripe about your solution IS valid.  Perhaps a
>better (in terms of array element comparisons) solution, using boolean
>flags...
:omitted:
>> The problem is the behaviour of 'and' plus the lack of 'break'.
>
>Noper.  The effect of the break statement can always be simulated by
>the use of boolean flags.  These will increase the amount of the
>book-keeping, but not change the order of an algorithm as far as the
>fundamental work unit(s) goes.

But I don't like them :-). Anyway, the idea of using different workarounds
for the same language flaw depending on the expected number of loops is
a bit rancid.
>
>The evaluation of the operands in boolean expressions can be
>controlled with nested if-thens.  For example, if I wanted to write
>
>    if a and b then ...
>
>but didn't want to bother evaluating b if a was false, I would write
>
>    if a then if b then ...
>
Try that with an 'else' clause, or with 'if a or b'. Try that with
'while a and/or b'. Your example is the only case that works
( DeMorganizing an OR to an AND won't work either ).

>These are applications of Boehm and Jacopini's Fundamental Control
>Structure Theorem.

The great thing about the C operators is that a code generator can be
made which generates exactly the same code for 'if(a&&b)' as for 
if(!(!a||!!!b)). Without any extra work, too; it happens as a side effect
if conditionals are handled properly (i've written one of these). In effect
they allow you to write spaghetti testing code neatly.

As for the lack of break, it is a fact of life that loops do not always
exit at the same point in the cycle as they start. Pascal ignores this.

>Do your homework BEFORE posting.  People are watching you, and paying
>for it.

Sorry, I don't feel that you have shot me *that* full of holes. I do regret
the posting, though, because it was essentially a negative contribution. Must
have been in a bad mood.

Someone pointed out that a goto could be used to break the loop. I had
effectively forgotten that. The only big program I have written in Pascal
was a subset Pascal compiler for an undergrad course. Since it was an
undergrad course, the word 'goto' automatically lost you points, and I had
to do lots of array searching of the above type. Eventually steam started
coming out of my ears. Some of it came back last week :-)

-- 
"You'll need more than a Tylenol if you don't tell me where my father is!"
						- The Ice Pirates
----------------------------------------------------------------------
Greg Smith     University of Toronto      UUCP: ..utzoo!utcsri!greg

b-davis@utah-cs.UUCP (07/22/86)

>In article <3130@utcsri.UUCP> greg@utcsri.UUCP (Gregory Smith) writes:
>	i :=1 ;
>	while i<1000 and x[i] <> 0 do
>		i := i+1;
>	if x[i] = 0 then writeln('zero at location', i )
>	else writeln('not found');

I personally like:

	for i := 1 to 1000 do
		if x[i] = 0 then goto DONE;
	i := 1001;
DONE:
	if i <= 1000 then writeln('zero at location', i )
	else writeln('not found');

If you don't like the 'goto' then flame someplace else.  I think that
goto's can be used in a structured manner.  The statement 'i := 1001;'
is needed since the value of 'i' is undefined after the 'for' statement.
What's nice is that a good compiler can look at the 'for' loop and 
determine that bounds checking is not needed on the 'if' statement.
The 'for' loop can also be done as a single machine instruction (on
none RISC machines).  A good optimizing compiler might even be able
to generate better code than a good optimizing C compiler.

I like Pascal for some reasons and I like C for other reasons.  The
reasons usually conflict.  I don't claim to be consistant.

-- 
Brad Davis	{ihnp4, decvax, seismo}!utah-cs!b-davis	
		b-davis@utah-cs.ARPA
One drunk driver can ruin your whole day.

gaynor@topaz.UUCP (07/22/86)

On using flags to simulate breaks, if a flag is not specifically
called for, I'ld rather use a break statement too.  Especially if the
amount of work it takes to do the book-keeping for a flag comes near
that of the unit of work.  In the long run, if I have a choice between
a program that runs 3 times faster than another, and they are both
quality code, not hard to figure which one'll get picked.  I guess the
point inadvertantly obscured in my first response was when you don't
got, make do without (or at least it's possible to do so).

On using unconditional branches to simulate breaks, the professors
here at RU have figured out an ingenious method to eliminate them
from student's code.  Microneurosurgery.  We are not physically
capable of typing the required string of characters - g... uh, go...,
um...  You know, a 'g' followed by a 'o', and then a 't', ...

> True, except it is quite common for a search test to produce a
> 'no-match' result very quickly most of the time, and to always take
> a long time to come up with match. The 'match' is the repeated test.
> Your point is well taken though.

Common indeed, but not the general case.  Your point is well taken
too, as recently I've read a little on Snobol's pattern matching.

On controlled evaluation of boolean operands, you can ALWAYS pull the
stunt off with the introduction of temporary booleans or duplicated
code.  Posting the proofs will surely draw fingers to N keys, hence
they're ommitted.  I wouldn't be caught dead coding any of those
transformations, though.

On flow of control, in general.  I haven't quite made up my mind on
all the issues, but Pascal is definitely lacking in some areas where C
is not.  This sentiment was lost in my original response.

> > Do your homework BEFORE posting.  People are watching you, and
> > paying for it.
>
> Sorry, I don't feel that you have shot me *that* full of holes. I do
> regret the posting, though, because it was essentially a negative
> contribution. Must have been in a bad mood.

I apologize for that last, it was definitely uncalled for.  Them's
fighting words...

Silver  {...!topaz!gaynor}

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

> What's wrong with this one?
>
>       label 1,2;
>       var i: integer;
>       ...
>       i :=1 ;
>       while i<=1000 do
>               if x[i] = 0 then goto 1
>               else i := i+1;
>
>       writeln('not found');
>       goto 2;
> 1:      writeln('zero at location', i )
> 2:      ...
>
>                 Martin Smith

"...avoid the use of jumps to express regular iterations and conditional
execution of statements, for such jumps destroy the reflection of the
structure of computation in the textual (static) structure of the program."

                        Pascal User Manual and Report, p. 32
--
/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\
Dave Haynie    {caip,ihnp4,allegra,seismo}!cbmvax!daveh

        "I don't feel safe in this world no more,
         I don't want to die in a nuclear war,
         I want to sail away to a distant shore
         And live like an ape man."
                                -The Kinks

        These opinions are my own, though for a small fee they be yours too.
\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/

zben@umd5.umd.edu (Ben Cranston) (07/23/86)

In article <3142@utcsri.UUCP> greg@utcsri.UUCP (Gregory Smith) writes:

> As for the lack of break, it is a fact of life that loops do not always
> exit at the same point in the cycle as they start. Pascal ignores this.

Over the last ten years I have implemented several (interpretive) languages
with the extended repeat syntax:

   repeat
      (block 1)
   until condition
      (block 2)
   endrep

The idea was to allow the entry point and exit point of the loop to differ
without breaking the rule that a loop has only one exit point.

   repeat
      fooptr := readnextfoo(foofile)
   until (fooptr=0)
      haveyourwaywithfoo(fooptr)
   endrep

In C one would write:

   while ( 0 != (fooptr = readnextfoo(foofile)) )
      haveyourwaywithfoo(fooptr);

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

marty@ism780c.UUCP (Marty Smith) (07/23/86)

In article <550@cbmvax.cbmvax.cbm.UUCP> daveh@cbmvax.cbm.UUCP (Dave Haynie)
  criticized the following program fragment by quoting form the Pascal bible.
>> What's wrong with this one?
>>
>>      label 1,2;
>>      var i: integer;
>>      ...
>>      i :=1 ;
>>      while i<=1000 do
>>              if x[i] = 0 then goto 1
>>              else i := i+1;
>>
>>      writeln('not found');
>>      goto 2;
>> 1:      writeln('zero at location', i )
>> 2:      ...
>>
>>                Martin Smith
>
>"...avoid the use of jumps to express regular iterations and conditional
>execution of statements, for such jumps destroy the reflection of the
>structure of computation in the textual (static) structure of the program."
>
>                       Pascal User Manual and Report, p. 32

But, Dave, the above quote is not part of the language definition; labels
and gotos are.  The original posting complained that x[i] was evaluated
twice.  This example avoids that problem with no loss of clarity, in my
opinion.  If you want to take my gotos from me, you'll have to pry them
from my cold, dead hands (or make me use Modula 2).

                          Martin Smith

ps.  Note that a C break statement is nothing more than a goto without
specifying the label.  Surely you must agree that a goto without a label
makes for more difficult understanding than a goto with a label.  If you
won't allow my use of labels in Pascal, then you must also disallow the
use of break in C.

tainter@ihlpg.UUCP (Tainter) (07/24/86)

> Challenge: given
> var	x: array [1..1000] of integer;
> write a code fragment to find the location of the first 0 in x. The
> condition that no zeroes exist must be distinguished.
> Further rules:
> 	- Standard Jensen & Wirth Pascal ( no break from loop )
> 	- *** x[i] must not be evaluated for i<1 or i>1000 ***
> 	- The search loop must be terminated as soon as a zero is found.
> 	- 'a or b', 'a and b' always evaluate both a and b ( I think
> 	   this is a rule in Jensen & Wirth )
> This is the best I can find:
> 	var i: integer;
> 	...
> 	i :=1 ;
> 	while i<1000 and x[i] <> 0 do
> 		i := i+1;
> 	if x[i] = 0 then writeln('zero at location', i )
> 	else writeln('not found');
> Greg Smith     University of Toronto      UUCP: ..utzoo!utcsri!greg

This is a better solution:

    var i : integer;
	notfound : boolean;
	x : array [1..1000] of integer;
    .
    .
    .
    i := 1;
    notfound := true;
    while (i<=1000) and notfound do
	if x[i] = 0 then
	    notfound := false
	else
	    i := i+1;
    if notfound then
	writeln('not found')
    else
	writeln('zero at location', i );
--j.a.tainter

steven@mcvax.uucp (Steven Pemberton) (07/24/86)

In article <3130@utcsri.UUCP> greg@utcsri.UUCP (Gregory Smith) writes:
> Given     var	x: array [1..1000] of integer;
> write a code fragment to find the location of the first 0 in x. The
> condition that no zeroes exist must be distinguished. Further rules:
> 	- Standard Jensen & Wirth Pascal ( no break from loop )
> 	- *** x[i] must not be evaluated for i<1 or i>1000 ***
> 	- The search loop must be terminated as soon as a zero is found.
> 	- 'a or b', 'a and b' always evaluate both a and b

What I find an elegant solution to this sort of problem is the following:

	var state: (searching, found, absent);
	    i: 1..1000;

	i:=1; state:=searching;
	repeat
	   if x[i]=0 then state:=found
	   else if i=1000 then state:=absent
	   else i:=succ(i)
	until state <> searching;

	case state of
	found: writeln('found at ', i);
	absent:writeln('not there')
	end

I like it because it is explicit and generalisable for searches with more
states. Note that i only takes values in 1..1000 and x[i] is only evaluated
once for each element.

I still think Jack Jansen's main point has been ignored in this discussion:
you run a C program that overruns an array, and it may run to completion, or
at best say "Memory fault - core dumped".

Do the same with a Pascal program, and you're quite likely to get something
like "Index out of bounds at line 123, value = -1". (Actually I just tried
it here, and with "x[1234]:=0", I got a compile-time error! The C version
ran without complaint).

This difference can make a huge difference to the time needed to get a
program running, and the confidence you have in it at the end. This
advantage far outweighs the minor notational inconveniences that this group
seems obsessed with.

Disclaimer: I think that there are programming languages FAR better than
both Pascal and C. However, I try to remain objective about all of them.

Steven Pemberton, CWI, Amsterdam; steven@mcvax.uucp

cc@pegasus.cs.ucla.edu (Naoto Kimura) (07/26/86)

In article <3130@utcsri.UUCP> greg@utcsri.UUCP (Gregory Smith) writes:
>
>Challenge: given
>
>var	x: array [1..1000] of integer;
>
>write a code fragment to find the location of the first 0 in x. The
>condition that no zeroes exist must be distinguished.
>
>Further rules:
>	- Standard Jensen & Wirth Pascal ( no break from loop )
>	- *** x[i] must not be evaluated for i<1 or i>1000 ***
>	- The search loop must be terminated as soon as a zero is found.
>	- 'a or b', 'a and b' always evaluate both a and b ( I think
>	   this is a rule in Jensen & Wirth )
>
>This is the best I can find:
>	var i: integer;
>	...
>	i :=1 ;
>	while i<1000 and x[i] <> 0 do
>		i := i+1;
>	if x[i] = 0 then writeln('zero at location', i )
>	else writeln('not found');
>
>weird,huh? Note that the condition 'x[i]=0' is evaluated twice ( once
>in the negative sense ), which would be unacceptable if we were searching
>an array of records and the test was expensive.
>

to avoid the evaluation of  ``x[i]=0'' you can do the following:

	var
	   i: integer;
	   f: boolean;
	...
	i := 0;
	repeat
	   i := i + 1;
	   f := x[i]=0;
	until f or i=1000
	if f then
	   writeln('zero at location', i )
	else
	   writeln('not found');

   The only thing that really looks weird in the above is the ``i := 0'',
which can cause trouble if ``i'' was to be defined as the subrange
1..1000 .


*********************************************************************
*** you've probably already heard the following at least a millon ***
*** times                                                         ***
*********************************************************************

    A difficult thing to write in Pascal is an interactive program.
Checking eof and eoln before reading anything can cause some problems,
since they are undefined.  Performing a read or readln before checking
the status of eoln or eof can be a problem if you use an empty file.
Either the read would fail since there isn't anything to read, or the
read or readln will set the eoln and eof, but will return some bogus
value in the variable.  These problems get to be pretty bad, since
different compiler handle eoln and eof differently.

Let's say we have the following:

	var
	   i : integer;
	...
	while not eof do
	   begin
	      writeln ('enter an integer : ');
	      readln (i);
	   end;

The prompt never appears until something is entered, since these
conditions cannot be checked before an attempt to read is made.
To solve this problem we might do the following:

	var
	   i : integer;
	...
	writeln ('enter an integer : ');
	while not eof do
	   begin
	      readln (i);
	      writeln ('enter an integer : ');
	   end;

   This solves the problem of getting no prompt before entering data,
but creates the problem of one extra prompt at the end.

   But then, you can't really complain about these problems because
Pascal wasn't designed to be used for interactive programming anyway.

tan@cae780.UUCP (07/29/86)

In article <3130@utcsri.UUCP>, greg@utcsri.UUCP (Gregory Smith) writes:
> 
> Challenge: given
> 
> var	x: array [1..1000] of integer;
> 
> write a code fragment to find the location of the first 0 in x. The
> condition that no zeroes exist must be distinguished.
> 
> Further rules:
> 	- Standard Jensen & Wirth Pascal ( no break from loop )
> 	- *** x[i] must not be evaluated for i<1 or i>1000 ***
> 	- The search loop must be terminated as soon as a zero is found.
> 
> This is the best I can find:
> 	var i: integer;
> 	...
> 	i :=1 ;
> 	while i<1000 and x[i] <> 0 do
> 		i := i+1;
> 	if x[i] = 0 then writeln('zero at location', i )
> 	else writeln('not found');
> 
> weird,huh? Note that the condition 'x[i]=0' is evaluated twice ( once
> in the negative sense ), which would be unacceptable if we were searching
> an array of records and the test was expensive.
> 
> Nobody can call this a special case... and I don't think my rules are
> unreasonable. The problem is the behaviour of 'and' plus the lack of 'break'.
> 
> -- 
> "You'll need more than a Tylenol if you don't tell me where my father is!"
> 						- The Ice Pirates
> ----------------------------------------------------------------------
> Greg Smith     University of Toronto      UUCP: ..utzoo!utcsri!greg



  I don't like your challenge.  If breaking out of a loop can't be considered
as a language feature for Pascal (although it is an extension to the original
Pascal language construct, it is more than common in these days),  we can't
consider the 'enum' construct as a legal feature for C, and anyone who come
up with a 'challenge' that needs the service of this 'enum' monster would 
have thrash C.  I suggest that broader view be taken into account when one
tries to 'compare' a programming with the other.

  The fully evaluation of conditional expression in Pascal may cause some
problem to some people, but they are not hard to get around.  The argued
'x[i] = 0 got executed twice == expensive' does not hold, since one 
such comparison is peanut compared to, say, 100 such operations.  For the
case of 'extremely complicated' data structure, PLEASE use a flag.

  I have done some 'medium' programs using both languages.  I don't have 
any pro or con on both of them.  I like and hate Pascal that it 'force'
me into a rigid track in programming.  I hate it because it takes me 
shorter time to complete my programs, even worse, it is so readable that
anyone can take over my job at anytime !

  I love and hate C also.  She gives me the luxury to fool around with
whatever possible.  I love her 'cause  I know I have a safe job.  No,
I don't love C that much, once it took me weeks to found out that I 
'accidentally' lost one of my mantissa bit in one of my crazy functions
in the 'greatest' program I have ever written (neat eh?).  Oh ya, you
definately can full Pascal by using variant record, but it is more fun 
doing it in C.

  The beauties of both miss C and Mr Pascal have been globally ad.
Sorry for not including these ad's in this article for I am not an
ad. agent.




   ----------------------------------------------------
   -                                                  -
   -  I speak for myself only.                        -
   -                                                  -
   ----------------------------------------------------

franka@mmintl.UUCP (Frank Adams) (07/31/86)

Articles concerning only Pascal should be in net.lang.pascal only.  Don't
followup to multiple newsgroups just because the article you are replying to
was in multiple newsgroups.

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