Language Syntax Suggestion

Hans-Dieter.Dreier@materna.de Hans-Dieter.Dreier@materna.de
Mon, 15 Mar 1999 18:27:57 +0100


--mWiDI6VKUqUnT4OA1xyrCNDNUfawxXBk
Content-type: text/plain; charset="ISO-8859-1"
Content-transfer-encoding: quoted-printable

>Hans-Dieter Dreier wrote:
>
>>>Shouldn't there be a comma before the "if"? I'd think that the if must
>>>be
>>>the first element (hence ordered) to make it a condition clause.
>
>Good question, this brings up the distinction that I made earlier about
>...
>the function. There is no case where we would wish the function name to
>be unordered and so it is always the first element of the function set.

Sorry, I didn't read read your first posting carefully. Otherwise I would h=
ave seen that it is so by definition.

>>...
>>may actually be better in pratice. I'd claim that everyone who has ever
>>programmed a line in BASIC can read it right from the start without any
>>explanation; I'd regard that as an advantage.
>
>I would too if what you said is correct. Just as you don't have a LISP
>parser in your head, I don't have a unary-operator/precedence parser in
>mine. I recently got through taking a Visual Basic class and I had to
>read your email several times to get the gist of how one applies some of
>your operators to normal loop structures. I am not faulting your
>approach, only you are finding out like I am that what one says to
>another seems perfectly clear to oneself but not so clear to the other.

Apparently it depends very strongly on one's background. Programmers who st=
arted with an imperative language would perhaps find my approach more reada=
ble, and programmers who started iwth a functional language or Lisp or Prol=
og or such like would be more famliar with yours.

>It was educational for me to observe the struggle of the students in my
>class as they were required to produce the result of statements in
>Visual Basic that required the knowledge of what took precedence. It was
>my observation that the average person couldn't understand anything more
>than short statements written in such a fashion and they invariably
>started throwing parentheses around the subsections of the expression so
>that they could figure out what the heck was going on. Only the very
>talented "geeks" or math students
>did very much better. It was for this reason that I am not entirely
>convinced of the argument that they are "clearer" in certain cases. Like
>the Chinese word symbology, unary operators always require a special
>symbol each time they are invoked, a symbol that we then must apply
>context rules to if we use the symbol for any other purpose. And if the
>expression is more than a few levels deep...

Usually expressions are relatively simple. If they get so complicated that =
more than, say, 4 levels of parentheses are needed, they would be broken up=
, using assignments or function calls.

>I think perhaps that you are trying to create a language that reads more
>like this email where I am trying to create a format that reads more
>like a mathematical expression. Mathematicians in ancient times took
>your approach and wrote down their discoveries in verbal form "the
>square of the hypotenuse...". What they discovered was that as the
>expressions got more involved it was impossible to describe your
>relation verbally to someone else unless you wrote an equation. And an
>equation is composed of those nasty parentheses and brackets without
>which we wouldn't be able to understand hardly anything.

I always thought precedence rules were quite common usage. Kids learn them =
in school as one of the first things in math. So I would assume that the co=
ncept of precedence rules should be well known to everyone; maybe not to th=
e extent found in some programming languages, however.

>For instance, you have the pairs do/od if/fi and case/esac. All these
>are just verbal equivalents of parentheses. Lets have the expression
>
>[(3 * 5)/(2 - 6)] - (2 + 4)(3 - 2)
>
>Is the next expression clearer?
>
>if do 3 * 5 od / do 2 - 6 od fi - do 2 + 4 od do 3 - 2 od

It certainly isn't. It would benefit from proper layout (as any example of =
your syntax certainly would too). Normally, you wouldn't find a constructio=
n in a program with more than at most two pairs of keyword parentheses in o=
ne line.

>>BTW, we have been discussing primarily the "executable" parts. I'd like
>>to
>>know how you would do the declarations and module structure as well.
>
>I do indeed need several examples, sorry I am such a dunderhead. I am
>very interested in how one applies the , and ; operators you are
>proposing.

If we omit possible procedence rule for "," and ";", it is easiest explaine=
d by looking at what happens inside the parser. The parser has two stacks (=
first in, last out) for operands and operators.

a, b; c, (d; (e, (f, g); h))

Token    operator stack  operand stack
a                            a
,            ,               a
b                            a b
                             a,b (Operator , gets executed and forms a list=
)
;                            (Operator ; gets executed immediately)
c                            c
,            ,               c
(            , (             c
d            , (             c d
;            , (             c
(            , ( (
e            , ( (           c e
,            , ( ( ,         c e
(            , ( ( , (       c e
f            , ( ( , (       c e f
,            , ( ( , ( ,     c e f
g            , ( ( , ( ,     c e f g
             , ( ( , (       c e f,g
)            , ( ( ,         c e f,g (Operator ")" matches "(" )
             , ( (           c e,(f,g)
;            , ( (           c
h            , ( (           c h
)            , (             c h
)            ,               c h
                             c,h

So the result is a list c,h. If you wonder why b d e f g have been written =
inthe first place, the answer is: Side effects. They could have been assign=
ments or routine calls which apply some changes to variables as well as ret=
urn a result (which may not be needed in this particular application).

The lines that do not have operations attached are used to execute stored (=
deferred) operators from the operator stack. Normally, infix operators need=
 to be stored until their right operand has been evaluated because they hav=
e to know both operands before they can evaluate their result.

Since the ";" operator does not need both of its operands at the same time =
but rather simply discards the left one, there is no point in storing it in=
 the operator stack. It is executed immediately instead.

In this model, operator precedence boils down to a simple comparison of the=
 "binding power" of the operator currently read to the binding power of the=
 operator found at stack top. If the operator on stack has higher binding p=
ower, it is popped and executed before the current one is pushed onto the s=
tack. Otherwise its execution is deferred and the current operator is pushe=
d on top of it.

>...
>You have to explain to me
>what you mean by "doing the declarations" and "module structures".

Most programs consist of more than just one expression. As their tast gets =
more complex, it is broken up into nested sub-tasts. Programmers find that =
some of these subtasks are needed more than once, usually with more or less=
 subtle modifications. So they invented the function. Also, it turns out th=
at there have to be data to store and forward results between functions (an=
d the outside world). A lot of these data have implicit relations to each o=
ther; they belong together. So programmers invented "structure"s to bundle =
those data and later combined them with the functions that operate on these=
 data to form "objects". To make error checking easier and to help understa=
nd the meaning of functions, data and objects, these are categorised; thing=
s than can be handled in the same way (say, integral numbers), are said to =
be of the same "type". And so on...

Programmers also found it nicer to break a program into pieces that are mor=
e manageable and called these "modules".

As you can find all these structures inside each program, you can see from =
this that a program really is a framework where expressions are used as bui=
lding blocks to make up the executable part. The "larger" building blocks (=
which house expressions, among otherthings) form the structure of the progr=
am. Because these structures usually contain a lot of substructures and thu=
s are spread of large portions of the programs, they need some special cons=
iderations to make it easier on the programmer. For example, use of special=
 delimiters (or sometimes indentation) helps the programmer as well as the =
compiler to properly identify structure boundaries (or at least allows issu=
ing a decent error message).

Because there are not so many larger superstructures (like classes) contain=
ed in a program, a certain typing overhead is accepted for hem if it clrifi=
ed program layout. To some extent this also applies to routines that are th=
emselves formed from simpler expressions.

I apologize if you already knew most of this or if it sounds rather general=
 ;).

Here is some example which I took from the excellent introduction into the =
Eiffel programming language by  Alan A. Snyder and Brian N. Vetter http://w=
ww.progsoc.uts.edu.au/~geldridg/eiffel/advance-intro/s7/#s7.1

I put vertical bars at the start of those lines that contain declarations a=
nd other stuff that I would regard as "structure".
-- This is a comment (no decrement operator).

|   class VEHICLE
  =

|   creation
|      start;
  =

|   feature {NONE}
|      color, num_passengers : INTEGER
      -- "private" data exported to NONE
  =

|   feature
|      Red, Blue, Green : INTEGER is unique;
      -- constants available to all clients
  =

|      start (new_num_passengers : INTEGER) is
|         require
            new_num_passengers >=3D 1;
|         do
            color :=3D Red; --default
            num_passengers :=3D new_num_passengers; --default;
            io.put_string ( "Hi!. I'm a new VEHICLE" );
            io.new_line;
|         ensure
            color =3D Red;
            num_passengers =3D new_num_passengers;
|         end; -- start
  =

|      set_color( new_color : INTEGER ) is
|         require
            new_color >=3D Red;
            new_color <=3D Green;
|         do
            color :=3D new_color;
|         end -- set_color
  =

|      set_num_passengers( new_num_passengers : INTEGER ) is
|         require
            new_num_passengers >=3D 0;
|         do
            num_passengers :=3D new_num_passengers;
|         end -- set_num_passengers
  =

|      get_color is
|         do
            Result :=3D color;
|         end -- get_color
  =

|      get_num_passengers is
|         do
            Result :=3D num_passengers;
|         end -- get_num_passengers

|      get_id is
|         do
            Result :=3D object_id;
|         end -- get_id
  =

|      invariant
         last_attrib >=3D 0;
  =

|   end -- VEHICLE

This example probably contains simplee expressions and more "structure" tha=
n you would normally find.
Please note that (due to precedence rules) hardly any parentheses are neede=
d inside the executable parts.

You can see that all executable stuff is enveloped by some declaration that=
 ensures that it has its proper place inside the overall structure that mak=
es up the program (or the class, in this example).

>Also, I enjoyed the website you pointed me to.

Me too. In Germany we have a proverb: "Nothing is useless; it still can ser=
ve as a bad example". (Not sure if I translated that correct).

>jeremydunn@ibm.net
>

--

Regards,

Hans-Dieter Dreier
(Hans-Dieter.Dreier@materna.de)=

--mWiDI6VKUqUnT4OA1xyrCNDNUfawxXBk
Content-type: text/plain; charset="ISO-8859-1"
Content-transfer-encoding: quoted-printable

IDENTIFIKATIONSANGABEN:
a23706a.txt IA5 DX-MAIL X.400 User Agent=

--mWiDI6VKUqUnT4OA1xyrCNDNUfawxXBk--