##### Quote

Julian Jones <jjo...@cmcvax.mckenna.edu> wrote:

> Program quadratic (input, output);

> {This program computes the answer, x, to the quadratic equation

> ax^2+bx+c=0}

> var

> a, b, c : real;

> const

> d = sqr(b)-(4*a*c);

As has already been said, you cannot compute a compile-time constant

based on run-time variables.

I suggest, here you simply declare a variable to hold the discriminant,

and compute it later, when you will have read the values needed:

var

d: real;

Alas, standard Pascal does not allow you to express your thoughts

lucidly. You cannot define run-time constants (i.e. constants

calculated from values obtained at run-time). You cannot even define

initial values for variables (which is the 1st work-around for your

problem coming to my mind).

##### Quote

> begin

> writeln ('Input the values of a, b, and c');

> readln (a) ;

> readln (b) ;

> readln (c) ;

Here is the place where you can compute the discriminant:

d = sqr(b) - 4*a*c;

##### Quote

> if d > 0 then

..

> else if d = 0 then

> begin

> writeln ('the root is');

> writeln (-b/2*a);

> end

Here is an error that will lead to wrong output: as the multiplication

operator does not bind closer than the division operator, you have to

code either

-b/(2*a)

or

-b/2/a

The same error is made below, in the d<0 branch, while it is not made

in the d>0 branch.

##### Quote

> else if d < 0 then

> begin

> writeln ('the roots are');

> writeln ((-b + sqrt(abs(d))/2*a));

> writeln ((-b - sqrt(abs(d))/2*a));

> end

While this part will compile alright, it is still wrong!

Your program will report two real solutions where the equation really

has two complex ones. Replace the preceding lines with:

begin

writeln ('the two roots are');

writeln (-b/2/a, ' + ', sqrt(abs(d))/2/a, '*i');

writeln (-b/2/a, ' - ', sqrt(abs(d))/2/a, '*i');

end

##### Quote

> else

> writeln ('I suck');

This is entirely superfluous, as the preceding conditions, viz.

##### Quote

> if d > 0 then

.

> else if d = 0 then

..

> else if d < 0 then

exhaust all possibilities.

In a language that allows for run-tim constants, the hole program

would be more lucid; in particular the declaration of d's datatype

and its value would not be separated by other stuff (which can be

several hundred lines of code, in more realistic examples).

In the following example, note that keyword delimiters, and types,

are written in uppercase, while identifiers are in lower case.

Note also that LOC REAL declares a real-typed variable, while REAL

(without the LOC) declares a constant. In the language used below,

everything declared in an IF part is visible throughout the remaining

part of the IF clause (i.e. from the point of declaration through

the IF, and THEN parts, down to the end of the ELSE part); same holds

for an ELIF part, where ELIF is an abbreviation for ELSE IF.

BEGIN # This program computes the answer, x, #

# to the quadratic equation ax^2+bx+c=0 #

LOC REAL a, b, c

; write (("Input the values of a, b, and c", newline))

; read ((a, b, c))

; IF REAL d = a*a - 4*a*c

; d = 0

THEN write (( "The root is ", -b/2/a, newline ))

ELIF REAL s = sqrt (ABS d)

; d > 0

THEN write ( ( "The two roots are:", newline

, (-b+s) / (2*a) , newline

, (-b-s) / (2*a) , newline

) )

ELSE write ( ( "The two roots are:" , newline

, -b/2/a, " + ", s/2/a, "*i", newline

, -b/2/a, " - ", s/2/a, "*i*, newline

) )

FI

END

FI is IF spelled backwards; this ends the IF statement, and thus

mends a syntactic ambiguity Pascal has inherited from Algol 60,

known as "the Problem of the Dangling ELSE".

You see, a well-designed language, such as Algol 68 (used in the

example above) lets you express your thoughts more lucidly. Too bad

that Niklaus Wirth impatiently has left the Algol 68 design team and

rushed into defining and implementing Pascal.