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