[comp.lang.misc] Turing programming language.

mart@euteal.UUCP (Mart van Stiphout) (01/18/89)

 have just been reading 'The Turing programming Language'
 in Communications of the ACM of Dec. 1988.
 At first I was enthousiatic because it has a number of things
 I line, such as dynamic arrays, nice strings, etc.
 But then look at the syntax. This is one hell of a mess.
 I especially hate the very ugly loop statement.
 And what about the cumbersome linked list example on
 page 1415.
 I wonder of Alan Turing likes it.

 Mart van Stiphout.
 mart@euteal.eutrc3.hp4nl

holt@turing.toronto.edu (Ric Holt) (01/18/89)

TURING VERSUS MODULA

These two languages are designed with many similar goals and are
very much alike in many ways.  Turing proper does not contain
separate compilation or systems programming features, which are
features of Modula and of Turing Plus.  A couple of areas where
Turing differs from Modula will be listed.

1) Turing is good for introductory programming.  For example, here
is a program that a high school student might write:

	var s : string := "*"
	loop
	    put length(s) : 3, " ", s
	    s := s + "*"
	end loop

The output of this program is:
	  1 *
	  2 **
	  3 ***
	  ...etc...

Likely the same student would get frustrated trying to program this in
Modula.

2) Turing is good for formal verification.  It has a weakest precondition
formal semantics.  Here is a Turing procedure that converts an integer,
such as 15, to a corresponding dollar string, in this case to $0.15.  This
function illustrates Turing's assertions (pre, post, assert), which are used
in verification:

	function dollarInt ( i : int ) answer : string
	    pre i >= 0     % Give restrictions on input
	    post           % Give requirements for correct result
	         answer(1) = "$" and
		 answer (* - 2) = "." and  % Decimal point two from end
		 i = strint( answer (2 .. *-3) + answer (*-1..*))
			% answer must represent same value as i
	    var t := intstr ( i )    % Convert i to a string
	    if length(t) = 1 then
		t := "00" + t
	    elsif length(t) = 2 then
		t := "0" + t
	    end if
	    assert length (t) >= 3   % Must be long enough to insert point
	    result "$" + t (1 .. *-2) + "." + t(*-1 .. *)
		% Result of function is $ then digits of t up to insertion
		% then decimal point then final two digits
	end dollarInt

Of course, you don't need to use assertions if you don't want to, and you
can ask the compiler to ignore them (by default, it generates code to
check them).

Finally, Turing Plus has various features that Modula doesn't have, such as:
	Exception handling (or does Modula have this?)
	True concurrency (processes run physically in parallel on
		shared memory multiprocessors)
	Nice numerical features (Turing or Numerical Turing are convenient
		for numerical analysis work).

mendell@turing.toronto.edu (Mark Mendell) (01/20/89)

I would like to know what you don't like about the syntax of Turing.  I admit
that as the main Turing development person, I am biased, but I like the Turing
syntax.

    You give two examples of features that you don't like:
	"I especially hate the very ugly loop statement"
	"And what about the cumbersome linked list example on page 1415."


I think that loop statement in Turing is simple and easy to use.  It is more
powerful than the equivalent Pascal loops.  For example:

(Please forgive minor Pascal syntax errors)

    Pascal				Turing

    while condition do			loop
	begin				    exit when not condition
	    ... code ...		    ... code ...
	end				end loop


    repeat 				loop
	... code ...		    	    ... code ...
    until condition			    exit when condition
					end loop

    
    { the one and a half loop }		/* the one and a half loop */
    read (i)				loop
    while i <> 0 do			    get i
	begin				    exit when i = 0
	    .... code ...		    ... code ...
	    read (i)			end loop
	end

As you can see, in Pascal, you have to repeat the 'read(i)' at the bottom of
the loop.  This can lead to problems maintaing the program, if only one of
the lines are ever changed.  In turing, there is only one copy of this code.


You have a better point with collections.  The Turing syntax:

    var symbolEntry : collection of
	record
	    name : string
	    location : int
	    /* ... more fields ... */
	    next : pointer to symbolEntry
	end record

    type SymbolPtr : pointer to symbolEntry


    var sym : SymbolPtr

    new symbolEntry, sym	/* ==  sym = (symbolEntry *) malloc (sz); */

    symbolEntry (sym).name := "fubar"
    symbolEntry (sym).next := nil(symbolEntry)


The 'collectionName(pointer)' syntax is more wordy than C or Pascal.  On the
other hand, it does tell you explicitly what the pointer points to.  In
addition, the syntax is deliberately identical to array subscripting.  This
is because the formal proof rules consider collection elements to be the same
as array elements.  A collection is just an array that can grow and shrink
using 'new' and 'free'
-- 
Mark Mendell
	    Computer Systems Research Institute    University of Toronto
	    Usenet:	{linus, ihnp4, allegra, decvax, floyd}!utcsri!mendell
	    Internet:	mendell@turing.toronto.edu
			mendell@turing.utoronto.ca

brian@ncrcan.Toronto.NCR.COM (Brian Onn) (01/21/89)

In article <11@euteal.UUCP> mart@euteal.UUCP (Mart van Stiphout) writes:
> have just been reading 'The Turing programming Language'
> in Communications of the ACM of Dec. 1988.
> At first I was enthousiatic because it has a number of things
> I line, such as dynamic arrays, nice strings, etc.
> But then look at the syntax. This is one hell of a mess.
> I especially hate the very ugly loop statement.

Gosh.  You just can please everyone, can you. 

How can you say this?  Compared to (what I've seen of) Modula, Turing is a
blessing.  It's syntax is also a heckuva lot cleaner than Pascal's.  I don't
know Ada, so can't make a comparison here.  Saying that Turing is "one hell
of a mess" is a very strong statement that just isn't true.

The loop statement is very clean and easy to work with:

	loop
		exit when ...
	end loop

It is very clear where the loop begins and ends, and under what conditions
it should terminate.  The exit test can be placed any where in the loop,
so "while <condition> do" and "do ... while <condition>"  loops can be
achieved with ease, as well as variations thereof.

> And what about the cumbersome linked list example on
> page 1415.

Sorry, I haven't read the CACM article, so can't comment here. But I
have written linked list code in Turing, and it wasn't that cumbersome.
The facilities provided by the language are very nice to work with, and
ensure that you are not doing what you shouldn't be doing with memory
pointers.  Records, collections, free() and nil() are all well implemented
in Turing.

> I wonder of Alan Turing likes it.

I am sure he would. 

Brian.
-- 
 +-------------------+--------------------------------------------------------+
 | Brian Onn         | UUCP:..!{uunet!attcan, watmath!utai}!lsuc!ncrcan!brian |
 | NCR Canada Ltd.   | INTERNET: Brian.Onn@Toronto.NCR.COM                    |
 +-------------------+--------------------------------------------------------+

mart@euteal.UUCP (Mart van Stiphout) (01/24/89)

 > I think that loop statement in Turing is simple and easy to use.  It is more
 > powerful than the equivalent Pascal loops.  For example:
 
 Let me explain my objections to the Turing loop syntax.
 My main objection is the location of the exit criterion. It is
 inside the loop and generally will be surrounded by (lots ?) of
 code. As  we all know, the correctness of loops
 can be shown by pre- and postconditions and the
 invariant relation. 
 In my view, the stop criterion should not be located somewhere in the
 middle of the loop. Furthermore, in my opinion your Pascal
 examples of loops proof their superiority to the Turing loops:
 the loop type is clear in a glance. I think it's ok to use different
 notations for different loops
 
 I'm not the greatest C fan, but I think C loops are just what
 you need for correct loops. Let me compare the C and Turing loops:
 
 C						Turing

						initialisation
 for ( initialisation; condition;  increment )	loop
 {			  			  exit when not condition
   ... code ...					  ... code ...
 }						end loop


 initialisation					initialisation
 do {						loop
   ... code ...		  			  ... code ...
 while condition		  			  exit when condition
						end loop

 And what do you think of the following C version of your 1.5 loop?
 while ( i = read() ) {
   ...code...
 }

 > You have a better point with collections.  The Turing syntax:
 
 I really like the idea of indexing linked list as if they were arrays.
 At the moment I am really fed up with the minimal support of
 languages like Pascal and C for linked lists. I always have
 to create records (structs) and `next' pointers. Accessing or
 adding list elements always requires extra source code for
 rather trivial operations.
 Why can't there be a programming language with type list that
 automatically allocates memory if needed and allows treatment of
 list in a similar way as arrays. Arrays are so much easier to
 handle, give fewer errors and the code looks much better.
 I'm really interested in other peoples opinions on these ideas.
 
 ---------------
 Mart van Stiphout
 Eindhoven University of Technology
 email: mart@euteal.eutrc3.hp4nl.mcvac.uucp

bradb@ai.toronto.edu (Brad Brown) (01/24/89)

In article <12@euteal.UUCP> mart@euteal.UUCP (Mart van Stiphout) writes:
 
> Let me explain my objections to the Turing loop syntax.
> My main objection is the location of the exit criterion. It is
> inside the loop and generally will be surrounded by (lots ?) of
> code. 
>...
> In my view, the stop criterion should not be located somewhere in the
> middle of the loop.

I can understand why you are hesitant to use the Turing syntax.  However,
as a former user of Turing and Turing Plus, I have to confess a real
affection for the Turing loop style.  I found that there were many 
situations where it fitted the problem better than forcing the exit
condition to be tested at the beginning or end of the loop.  This is
especially true where you have a read-process-read-process... loop
with hairy initialization.  When you have to test for conditions at
the beginning or end of the loop you have to unroll some initialization
code, which is messy.  Furthermore, you may have several distinct
conditions inside the loop that could cause exit, like EOF or out of
memory or bad syntax on reading.  I have found that these situations
usually require something like C's "break", but are handled much
more naturally by the Turing "exit when".

Now, I agree that there is more responsibility on the part of the 
programmer to maintain good style and make the exit conditions 
visually stand out.  I got used to having whitespace around the
exit when, and sometimes would have some nice bold comments to
help it stand out more.  

Let me add that I came to Turing Plus with a strong background in
Pascal and C.  I am currently a professional level C programmer,
and have reasonable experience in a variety of other languages.
I was exposed to Turing Plus in a compilers course and an operating
systems course, in both cases using it *a lot* to build reasonably
large programs.  I found the syntax to be, on the whole, easier and
more intuitive than either Pascal or C, and REALLY LIKED the language.
I don't use it any more because most of my programming either Lisp
or for other people, for whom I have to use C.  I just wish there
was a good Turing Plus compiler for the PC!!!

					(-:  Brad Brown  :-)
					bradb@ai.toronto.edu

db@lfcs.ed.ac.uk (Dave Berry) (01/24/89)

In article <12@euteal.UUCP> mart@euteal.UUCP (Mart van Stiphout) writes:
> In my view, the stop criterion should not be located somewhere in the
> middle of the loop. Furthermore, in my opinion your Pascal
> examples of loops proof their superiority to the Turing loops:
> the loop type is clear in a glance.

Two points:
  1) exits from loops make some programs easier to write and understand.
  2) a slightly different indentation scheme can make them just as easy to
     read (IMO) as Pascal type loops.
     
The first point is discussed with supporting psychological evidence in
the following article:

@Article(soloway2,
      Author="E. Soloway and J. Bonar and K. Ehrlich",
      Title="Cognitive Strategies and Looping Constructs: An Empirical Study",
      Journal="CACM",
      Volume="26",
      Pages="853-860",
      Year="1983")

The second point is clearly subjective, but I think that if you don't
indent exit statements, loops are easy to read:

exit indented:				exit not indented:

initialisation				initialisation
loop					loop
  some code				  some code
  exit when condition			exit when condition
  some more code			  some more code
end loop				end loop

> I'm not the greatest C fan, but I think C loops are just what
> you need for correct loops.

Presumably you want to exclude the break statement!

Dave Berry,	Laboratory for Foundations of Computer Science, Edinburgh.
		db%lfcs.ed.ac.uk@nss.cs.ucl.ac.uk
		<Atlantic Ocean>!mcvax!ukc!lfcs!db

gateley@m2.csc.ti.com (John Gateley) (01/25/89)

In article <12@euteal.UUCP> mart@euteal.UUCP (Mart van Stiphout) writes:
< Let me explain my objections to the Turing loop syntax.
< My main objection is the location of the exit criterion. It is
< inside the loop and generally will be surrounded by (lots ?) of
< code. As  we all know, the correctness of loops
< can be shown by pre- and postconditions and the
< invariant relation.

This point does not really follow: at any point in the loop where there
is an exit (and Turing loops can have more than one exit I think), you
know the conditions associated with the exit. Thus, the Hoare style
axiomatic semantics can still be used to prove things about this loop.

< In my view, the stop criterion should not be located somewhere in the
< middle of the loop. Furthermore, in my opinion your Pascal
< examples of loops proof their superiority to the Turing loops:
< the loop type is clear in a glance. I think it's ok to use different
< notations for different loops

This depends on what you call a loop. In Scheme (which of course has
loops superior to any language :^), there are no `Pascal' style loops.
Loops are done using recursion (and in particular tail recursion). This
allows more general and powerful loops to be written. It just dependss
on what style of programming you wish to use.

< I really like the idea of indexing linked list as if they were arrays.
< At the moment I am really fed up with the minimal support of
< languages like Pascal and C for linked lists. I always have
< to create records (structs) and `next' pointers. Accessing or
< adding list elements always requires extra source code for
< rather trivial operations.
< Why can't there be a programming language with type list that
< automatically allocates memory if needed and allows treatment of
< list in a similar way as arrays. Arrays are so much easier to
< handle, give fewer errors and the code looks much better.
< I'm really interested in other peoples opinions on these ideas.

I am not quite sure what you mean about 'accessing them as if they were
arrays', but any Lisp language, and other languages as well, provide the
list capabilities you are asking for: automatic allocation, easy treatment
of lists etc. 

John
gateley@tilde.csc.ti.com

mike@arizona.edu (Mike Coffin) (01/25/89)

From article <12@euteal.UUCP>, by mart@euteal.UUCP (Mart van Stiphout):

>  Let me explain my objections to the Turing loop syntax.  My main
>  objection is the location of the exit criterion. It is inside the
>  loop and generally will be surrounded by (lots ?) of code. As we
>  all know, the correctness of loops can be shown by pre- and
>  postconditions and the invariant relation.  In my view, the stop
>  criterion should not be located somewhere in the middle of the
>  loop. Furthermore, in my opinion your Pascal examples of loops
>  proof their superiority to the Turing loops: the loop type is clear
>  in a glance. I think it's ok to use different notations for
>  different loops
I'm not sure what the pre- and post-condition have to do with where
the loop exit is.  The loop invariant has nothing to do with where the
exit is, and the other part of the post-condition is exactly the exit
condition.  Again, it doesn't matter where the exit is.

In a practical sense, it is very useful to exit a loop from the middle
sometimes.   Almost all programming languages recognize this and
provide some way to do it:  C has break, Pascal has goto, etc.  Turing
just attempts to make this less of an exception.  With proper
formatting, it is just as obvious what kind of loop it is.

>  Why can't there be a programming language with type list that
>  automatically allocates memory if needed and allows treatment of
>  list in a similar way as arrays.

There are lots of them.  CommonLisp, Scheme, Icon, etc.


-- 
Mike Coffin				mike@arizona.edu
Univ. of Ariz. Dept. of Comp. Sci.	{allegra,cmcl2}!arizona!mike
Tucson, AZ  85721			(602)621-2858

w-colinp@microsoft.UUCP (Colin Plumb) (01/25/89)

mart@euteal.UUCP (Mart van Stiphout) wrote:
>  Let me explain my objections to the Turing loop syntax.
>  My main objection is the location of the exit criterion. It is
>  inside the loop and generally will be surrounded by (lots ?) of
>  code. As  we all know, the correctness of loops
>  can be shown by pre- and postconditions and the
>  invariant relation. 

Easy: the loop invariant must be true at the "exit when" line.
How the loop is rotated is pretty trivial.  It just turns out to
be easier to show the entrance by the top of the loop and have
an explicit mark for the exit.

As you yourself show with the "while (c = getchar())" example, you
can pull the same stunts in C, but they're messier if the condition
comma-expression gets bigger.

(For small cases, though, for(...;...;...) is *very* handy.)

WSL, a highly C-influenced langauge has a similar construct, quif
(quit if).  I'd rather use C, but it is nifty.
-- 
	-Colin (uunet!microsof!w-colinp)

wsmith@m.cs.uiuc.edu (01/26/89)

I can make a direct mapping from Turing to C (pardon any syntactic errors):

loop				|	while (1){
				|		
	exit when condition1	|		if(condition1) break;
				|
	exit when condition2    |		if(condition2) break;
				|
end loop			|		}

Now my question, in this framework, is there a Turing equivalent to the C:

		if (condition3) continue;

If not, it is a serious omission.

Bill Smith
wsmith@cs.uiuc.edu
uiucdcs!wsmith