Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Pronouns in programming language?

50 views
Skip to first unread message

John Fremlin

unread,
Feb 27, 2000, 3:00:00 AM2/27/00
to
Has any programming language/compiler implemented pronoun like
constructs? For example:

if variable_with_long_name == '2 ,
{ do this; }
if it == '3 , # equivalent to: variable_with_long_name == '3
{ do that }


Alternatively or in addition, elision (automatic scope changing),
for example:

if variable_with_long_name == '2 ,
{ do this; }
if == '3 , # equivalent to: variable_with_long_name == '3
{ do that }

Would it be a good idea? I don't think that it'd be too difficult to
implement in my project . . .

[I can think of some examples. Lisp LET (typically implemented as an
anonymous procedure) permits you to assign names to expressions for very
limited scopes. Cobol lets you elide comparison operands, something like
IF FOO-BAR LESS THAN 12 OR GREATER THAN 42 THEN ... -John]

Axel Schairer

unread,
Feb 28, 2000, 3:00:00 AM2/28/00
to
[Sorry, the post got longer than I thought it would. Also not the
whole of it might be entirely on-topic for c.c.]

[Language design has always been within c.c's purview so long as it's
at least within hailing distance of topics that affect the way you'd
build a compiler. -John]

John Fremlin <v...@altern.org> writes:
> Has any programming language/compiler implemented pronoun like
> constructs?

Our Moderator wrote:
> [I can think of some examples. Lisp LET (typically implemented as an
> anonymous procedure) permits you to assign names to expressions for very
> limited scopes.

That would be

(let ((it very-long-variable-name))
(cond ((equal it key1) ...)
((equal it key2) ...)
...))

but you'd probably rather use a case form for this in Common Lisp.

Also, the Common Lisp macro system can be used to implement anaphora.
There are, as far as I can remember, discussions of this kind of thing
in Peter Norvig: _Paradigms of AI Programming -- Case Studies in
Common Lisp_, and also in Paul Graham: _On Lisp_.

As an example, you can write a macro for `anaphoric if' such that the
then and else clauses can refer to the value of the condition by the
variable `it'. (Something like this is in Graham's book.)

(defmacro if-a (condition then-clause &optional (else-clause nil))
`(let ((it ,condition))
(if it
,then-clause
,else-clause)))

This is expanded at compile time so that your compiler, instead of,

(if-a (lookup-entry key database)
(process it)
(add-new-entry-to-database-and-process-that))

really compiles

(let ((it (lookup-entry key database)))
(if it (process it) (add-new-entry-to-database-and-process-that)))

(This is actually useful in Lisp because everything but NIL is
interpreted as true, and according to a common convention you would
probably specify LOOKUP-ENTRY to either return the entry it found, or
NIL if there was no entry. So in the then-clause, IT would have a
meaningful value.)

> Would it be a good idea? I don't think that it'd be too difficult to
> implement in my project . . .

Sometimes this can be a nice feature, however there are problems with
it. If you nest such constructs you'll end up shadowing one IT by
another. So you might run the risk that some seemingly unproblematic
editing step might break your code. If you change the snippet on the
left to the one on the right

(if-a condition1 | (if-a condition1
| (if-a condition2
| (g it)
(f it) | (f it)) ; <=== Bug?
(...)) | (...))

you now apply F to the value of CONDITION2, whereas you applied it to
the value of CONDITION1 before the change. Therefore, some people
prefer to explicitly specify the name for the anaphoric reference, as
in

(if-a my-it condition
(... my-it ...)
(...))

or some such. This can also be done in CL's macro system.

In the examples you give in your post it does, to me, not seem to be
worth the trouble because just using abbreviatinons for `variables on
the left hand side of equations in the condition of if-expressions'
seems to be too ad hoc, and generalising to arbitrary expression would
mean you have to decide and specify how often the expressions you
abbreviate are evaluated. Also what does `it' refer to if you don't
have a test for equality as the condition?

In summary, it could be nice to have, but you have to balance the
advantages and disadvantages.

Hope this helps,
Axel

Richard Weaver

unread,
Feb 28, 2000, 3:00:00 AM2/28/00
to
John Fremlin <v...@altern.org> writes:
>
>Has any programming language/compiler implemented pronoun like
>constructs? For example:
>
> if variable_with_long_name == '2 ,
> { do this; }
> if it == '3 , # equivalent to: variable_with_long_name == '3
> { do that }
>... [snip}

There was an assembler (or modification to the IBM assembler? due to
Knuth?) for the IBM 650 where, as best I can recall, "points" (in the
sense of "here") could be defined. In the context of this suggestion,
a "point" said any "it" following, until "point" is redefined, is a
reference to this point. After a redefinition any following "it" was
a reference to the new definition. Points were numbered (a max of
10?). The motivation would have been to save space in the symbol
table on a machine with a memory of 10,000 bytes (I think that was the
common configuration).

For more current languages, the IF examples in the subject post look a
lot like case statments/constructs.

dick w
[Knuth used this in his MIX assembler, and it showed up in the PDP-11
Unix assembler as well. -John]

Terrence Enger

unread,
Feb 28, 2000, 3:00:00 AM2/28/00
to
On 27 Feb 2000 02:53:06 -0500, John Fremlin <v...@altern.org> wrote ...

> Has any programming language/compiler implemented
> pronoun like constructs?

Hmm. That's what I thought a reference is in C++.

Terry.

pwa...@my-deja.com

unread,
Feb 28, 2000, 3:00:00 AM2/28/00
to
John Fremlin <v...@altern.org> wrote:
> Has any programming language/compiler implemented pronoun like
> constructs?

Shell languages (like bash, tcsh, etc), have "!" notation to refer to
previously typed in commands. For example, "!!" is the previous
command, "!33" is command number 33 in the saved history of commands,
and "!?foo" is the most recent command containing the string "foo".
See the man page for more examples.

The (old traditional) unix "bc" command provides a calculator, where
"." refers to the previous result. I think of seen variants of that
facility in other math packages, such as Maple.

The "Perl" programming language has a default "scalar" variable, "$_"
which is used when none are specified (and a separate list version
"@_"). Many Perl expressions will refer to one of these two variables
unless explicitly overridden. Many looping constructs will use the
"$_" scalar variable as the index variable by default. Arguments to
procedures are passed in the "@_" list variable. Find a good Intro to
Perl book for more details.

My concern with your example is with the "modifiability" of programs
using your pronouns or elisions. When lines of code start getting
added between the line producing the value and the line consuming it,
the human reading the code can get more and more confused. Since you
use the word "pronoun", I get the feeling that you want the program to
be able to refer to the results of *particular* other parts of the
program by position or adjacency. And my complaint is that adjacency,
at least, can get arbitrarily fuzzy as code gets added.

The Shell "!" notation is geared towards referring to the text of
typed in commands.

The bc "." notation is geared towards a "current result", or perhaps
the top of a stack of results in a stack machine.

The Perl "_" variables are special "current result" variables,
modified implicitly by most commands. All the commands modify the
same implied variable. So one thing that needs to be understood in
order to read Perl programs is how and when these implied variables
get modified. It might sound complicated, but I haven't had any
confusion in practice.

Perl string pattern matching can be a different story. There you us
what are called "regular expressions" to match strings, possibly
saving pieces of the matched string. The pieces are stored in
numbered variables -- the first piece in "$1", the second in "$2", and
so forth. The problem is that if you execute another command that
modifies these variables, all the original values are lost. After
getting burned my this a couple times while "evolving" Perl programs,
I learned just to assign all the numbered variables to named variables
(for example, "$tag = $1 ; $value = $2 ;" etc.). And hence my
nervousness about adjacency rules a couple paragraphs back.

Perl's got the most interesting and useful notion of implied variables
that I know of, though I have not done a survey. The shell "!" notation
refers to the text of typed in commands rather than variables, so is
more an aid to typing in shell programs interactively than making the
programs more terse.

I hope you find my response useful.

-- Perry


> [I can think of some examples. Lisp LET (typically implemented as
> an anonymous procedure) permits you to assign names to expressions

> for very limited scopes. Cobol lets you elide comparison operands,


> something like IF FOO-BAR LESS THAN 12 OR GREATER THAN 42 THEN
> ... -John]

I've also heard that some languages have experimented with permitting
n-ary comparisons (eg, "1 < x < 10" instead of "x > 1 && x < 10", but
they always conclude that its a mistake. Hard to understand code gets
produced, and I think there's a parsing problem, but I forget what.

Joel Jones

unread,
Feb 28, 2000, 3:00:00 AM2/28/00
to

John Fremlin <v...@altern.org> writes:

>Has any programming language/compiler implemented pronoun like
>constructs?

Both Hypertalk and Applescript on the Macintosh provide such pronouns.

Joel Jones
jjo...@uiuc.edu

Lieven Marchand

unread,
Feb 28, 2000, 3:00:00 AM2/28/00
to
John Fremlin <v...@altern.org> writes:

> Has any programming language/compiler implemented pronoun like
> constructs?

It has been done in Common Lisp. Paul Graham in his book "On Lisp"
calls these things anaphoric macros and devotes chapter 14 to them.

A nice example is his anaphoric AND:

(aand (owner x) (address it) (town it))

which returns the town (if there is one) of the address (if there is
one) of the owner (if there is one) of x.

An even more mindbending example is alambda

(alambda (x) (if (= x 0) 1 (* x self (1- x)))).

RKRayhawk

unread,
Feb 28, 2000, 3:00:00 AM2/28/00
to
The moderator mentioned that

<< Cobol lets you elide comparison operands, something like
IF FOO-BAR LESS THAN 12 OR GREATER THAN 42 THEN ...
>>

COBOL also has condition names which in effect allow elision of
subject field name and relational! The condition name feature includes
ranges and list of values. You can code something like

IF condition-name ...

That facility requires one specification of the condition in a
declaration of the condition name, and then permits numerous
references to it by its mere name. (This creates some challenges for
grammar writers when parsing things like

IF A = B AND C ...

where C could be an implied object of the relational condition like
A=C or it could be a condition name. ((By the way COBOL has a
tradition of calling the front and back parts of relational expression
the subject and object)).

COBOL also definitely allows suppression of the subject of relational
expressions in its case constructed, the EVALUATE statement (added in
COBOL '85). Simplest use of this implies the equality relational. Yet,
also, the surface of the cases can have significant topology which is
projected by the header of the EVALUATE statement, each case (the WHEN
clauses) can even variably suppress nodes in that topology with an
'ANY' token. ((Thus it is not a lexical portion of a relational
expression that is elided, but insted that whole relation in the
mix. EVALUATE topologies are actually all logical AND surfaces,
expressed with an 'ALSO' token.)) The 'ANY' token can be used the
otherway around too; implying a nondescript node in the topology when
used in the header, leaving the cases to list out the full relation
subject+relop+object, or dummying in 'TRUE' (yet another way to
nullify a node in the topology!).

With any interest in implied subjects or objects, you might want to
study the history of the rules for the attribution of NOT in implicit
conditional expressions in COBOL. For example, in

IF NOT A = B AND C

this leads to what you might call DeMorgans nightmare (two nights in a
row since C could be a variable or a condition name!). And if I
remember the history (assuming C is a variable), the expression

IF A NOT = B OR C ...

might have had different semantics at times. (EVALUATE never gets
into this trouble... A.F.A.I.K.)

So if you are going to imply some subjects in anything you develop,
beware of the potential problems with negation or inversion. In a way
(a way that I have not thought out too completely) the problem here is
partly precedence. COBOLers are not much interested in precedence, so
the language standard has tried to glide in the path of 'what would it
mean in natural language?', (quite an undertaking for a multinational
committee).

Partly also this later problem is sourced in the fact that the chunk
of language that goes by the spelling N-O-T participates in
not-relationals and not-if-conditionals. Languages like C avoid this
by lexical props (evolved partly accidentally, and partly
intentionally). We can see that the tilde (~) and the exclamation
point (!) have different functions. Less obvious, but just as
important, digraphs like exclamation point + equal (!=) are actually
lexically distinct from simple exclamation point (!). Let me
illustrate this

~var_int /* produces binary inverse */
!var_int /* evals the NOT of evaluated var */
var_int != 0 /* a specific relation, NOT EQUAL */

If you try to implement a language that implies subjects (by means of
pronouns of elision), then you may wish to figure how the nots will be
applied. Distinct lexical matter to mark distinct kinds of negative
logic is helpful, but in a modern context the idea implied operands
with negative logical indications must be worked out with your plan
for precedence. And it must be clear to the coder what it will mean.

Best Wishes,

Robert Rayhawk
RKRa...@aol.com

Hamish Atkinson

unread,
Feb 28, 2000, 3:00:00 AM2/28/00
to
Visual basic allows you to manually reduce the scope using the WITH
construct eg:

Set rstSources = MyDb.OpenRecordset("Sources", dbOpenTable, )
With rstSources
.AddNew
!Name = NewSource
.Update
.Bookmark = .LastModified
AddSource = !SourceID
End With

This eliminates the need to type the variable name over and makes the code
easier to read.

H. Ellenberger

unread,
Feb 28, 2000, 3:00:00 AM2/28/00
to
John Fremlin wrote:

> Has any programming language/compiler implemented pronoun like
> constructs?

I see some problems with possible ambiguities. What if the 'do this'
also has conditional statements, even multiply nested?

This might be the reason why many languages have the 'select case'
construct,

which could generalized towards

select (variable_with_long_name)
case cond1a or cond1b and not cond1c: do this
case cond2: do that
else: fallback
end select

HE

Torben AEgidius Mogensen

unread,
Mar 3, 2000, 3:00:00 AM3/3/00
to
John Fremlin <v...@altern.org> writes:

>Has any programming language/compiler implemented pronoun like

>constructs? For example:

> if variable_with_long_name == '2 ,
> { do this; }
> if it == '3 , # equivalent to: variable_with_long_name == '3
> { do that }


In the interactive system of Standard ML, "it" refers to the value of
the expression evaluated at the most recent prompt. SO, you can write
something like

- 2*(3+4);
> val it = 14 : int
- it*7;
> val it = 98 : int
-

where the "-" is the prompt and the result is shown after the ">".
Basically, an expression at the prompt is evaluated like the
declaration "val it = <expression>". Subsequent expressions creates
new instances of the name "it" and binds these to the new values.

Torben Mogensen (tor...@diku.dk)

James Jones

unread,
Mar 3, 2000, 3:00:00 AM3/3/00
to
Burroughs Algol, sort of anticipating assignment operators, provided
something like that, kind of an "ibid" :-). I don't have a manual
at hand, but I think an example would look something like

a[i, j] := * + x

where the * was the "ibid" operand.

James Jones

Axel Schairer

unread,
Mar 3, 2000, 3:00:00 AM3/3/00
to
pwa...@my-deja.com writes:
> I've also heard that some languages have experimented with permitting
> n-ary comparisons (eg, "1 < x < 10" instead of "x > 1 && x < 10", but
> they always conclude that its a mistake. Hard to understand code gets
> produced, and I think there's a parsing problem, but I forget what.

Lisp has that for many operators and comparisons: (+ x1 x2 x3 x4),
(< x1 x2 x3 x4), and so on. I certainly have never heard that this
was considered a mistake in the lisp community. But then, because of
lisp's syntax, there is no parsing problem here at all.

I would be interested in knowing which other problems you have thought
or heard of, in particular, is the code hard to understand because of
the parsing problems (for the programmer), or are there other issues
involved?

Axel

Charles E. Bortle, Jr.

unread,
Mar 6, 2000, 3:00:00 AM3/6/00
to
Hello,

RKRayhawk <rkra...@aol.com> wrote in message


> The moderator mentioned that
> << Cobol lets you elide comparison operands, something like
> IF FOO-BAR LESS THAN 12 OR GREATER THAN 42 THEN ...
> >>
>
> COBOL also has condition names which in effect allow elision of
> subject field name and relational! The condition name feature includes
> ranges and list of values. You can code something like


COBOL also has the MOVE CORRESPONDING verb to move data
with the same field name between records, which is pronoun-like.
--
Charles cbr...@ix.netcom.com
* http://pw2.netcom.com/~cbrtjr/wrdthing.html *

Charles E. Bortle, Jr.

unread,
Mar 6, 2000, 3:00:00 AM3/6/00
to
Hello,

(This is somewhat long...)

<pwa...@my-deja.com> wrote in message news:00-0...@comp.compilers...


> John Fremlin <v...@altern.org> wrote:
>
> Perl string pattern matching can be a different story. There you us
> what are called "regular expressions" to match strings, possibly
> saving pieces of the matched string. The pieces are stored in
> numbered variables -- the first piece in "$1", the second in "$2", and
> so forth. The problem is that if you execute another command that
> modifies these variables, all the original values are lost. After
> getting burned my this a couple times while "evolving" Perl programs,
> I learned just to assign all the numbered variables to named variables
> (for example, "$tag = $1 ; $value = $2 ;" etc.). And hence my
> nervousness about adjacency rules a couple paragraphs back.

The input language FMQ for the FMQ and LLGen written by Jon Mauney at
the University of Wisconsin at Madison uses this approach to indicate
which semantic stack entries are to be used for which parameters of
the semantic routines called by the LL(1) parser driver which uses the
tables generated by FMQ and LLGen.

I have never used FMQ nor LLGen, but I wrote my own parser generator
which takes the FMQ language as its input. I generate a semantic
dispatch routine, which is Included in the Pascal source for the
semantic processing module of the compiler I am writing. In order to
associate the correct $1, $2, etc with the appropriate parameter in
the acutal call to the routines in the dispatcher, I use a
thunking-like approach. I have created an array in the semantic
module:

ASP : ARRAY [1..MAX_SEMANTIC_ACTION_PARAMS] OF SEMANTIC_RECORD_POINTER;
(* ACTION SYMBOL PARAMETERS *)

(MAX_SEMANTIC_ACTION_PARAMS is a constant that I have picked as the
max number of params that any semantic action routine can use, so it
is a fixed value and not generated by the parse generator.)

The numeric value of the $ param is used to generate an index into ASP
so that the appropriate semantic record pointer is accessed for each
param of the called semantic routine.

The pointers to the appropriate semantic stack entries get put into
the corrrect ASP entries by the parser when it is processing a
semantic actiton symbol such as SA_PROCESS_CONSTANT_DEFINITION($1, $2,
$3) in the routine below:

PROCEDURE PROCESS_ANY_SEMANTIC_ACTION_PARAMETERS_ON_STACK;
VAR
J : INTEGER;
TOP_TOKEN : SYNTAX_TOKEN;
SEM_STACK_INDEX : INTEGER;
PARAM_CODE : INTEGER;
BEGIN
FOR J := 1 TO MAX_SEMANTIC_ACTION_PARAMS DO ASP[J] := NIL;
J := 1; (* RESET TO POINT TO ASP[1] *)
LL_ONE_PARSE_STACK^.TOP(TOP_TOKEN);
WHILE (TOP_TOKEN.GET_SYMBOL_TYPE = ACTION_SYMBOL_PARAM_FLAG) DO
BEGIN
LL_ONE_PARSE_STACK^.POP(TOP_TOKEN);
PARAM_CODE := TOP_TOKEN.GET_SYMBOL_IDENT;
IF PARAM_CODE = 0 THEN
BEGIN
SEM_STACK_INDEX := LL_ONE_SEMANTIC_STACK^.GET_LEFT_INDEX;
END
ELSE
BEGIN
PARAM_CODE := PARAM_CODE - 1;
SEM_STACK_INDEX := LL_ONE_SEMANTIC_STACK^.GET_RIGHT_INDEX +
PARAM_CODE;
END;
ASP[J] :=
LL_ONE_SEMANTIC_STACK^.GET_POINTER_TO_STACK_ENTRY(SEM_STACK_INDEX);
INC(J);
LL_ONE_PARSE_STACK^.TOP(TOP_TOKEN);
END;
END;


The dispatch routine generated by the parse table generator looks like
this (Note: I have manually commented out the calls for which I have
not written the semantic routine yet, thusly {-- --} the (* *)
comments and all of the code is generated by the parse table
generator. The white space between the implemented calls and the
unimplemented is also entered manually by me):

(**************************************************************************)
(* THIS IS A SEMANTIC ACTION DISPATCH FILE FOR LL(1) PARSER *)
(* GENERATED FROM INPUT FILE [PASDEF43.LL1] *)
(**************************************************************************)

PROCEDURE TAKE_SEMANTIC_ACTION(SEMANTIC_ACTION_REQUESTED : INTEGER);
PROCEDURE PROCESS_UNIMPLIMENTED_SEMANTIC_ACTION_REQUEST;
VAR
SEMANTIC_ACTION_TOKEN_TEXT : STRING;
BEGIN
{ WRITELN('UNIMPLIMENTED SEMANTIC ACTION REQUEST');}
ACCESS_TOKEN_TEXT(SEMANTIC_ACTION_REQUESTED,
SEMANTIC_ACTION_TOKEN_TEXT);
WRITELN('UNIMPLIMENTED SEMANTIC ACTION REQUEST'+' ['+
SEMANTIC_ACTION_TOKEN_TEXT+']');
END;
BEGIN
CASE SEMANTIC_ACTION_REQUESTED OF

(**************************************************************************)
(*------------------------------------------------------------------------*)

{-- ASC_LOGICAL_BEGINNING_OF_PROGRAM:
SA_LOGICAL_BEGINNING_OF_PROGRAM;
ASC_LOGICAL_END_OF_PROGRAM:
SA_LOGICAL_END_OF_PROGRAM;
ASC_PROCESS_PROGRAM_HEADING:
SA_PROCESS_PROGRAM_HEADING(ASP[1], ASP[2]);
ASC_PROCESS_EMPTY_PROGRAM_HEADING:
SA_PROCESS_EMPTY_PROGRAM_HEADING;--}

ASC_PROCESS_PROGRAM_ID:
SA_PROCESS_PROGRAM_ID(ASP[1], ASP[2]);

{-- ASC_PROCESS_FID_LIST:
SA_PROCESS_FID_LIST(ASP[1], ASP[2]);--}

ASC_START_ID_LIST:
SA_START_ID_LIST(ASP[1], ASP[2]);
ASC_COPY:
SA_COPY(ASP[1], ASP[2]);
ASC_NEXT_ID_LIST_ENTRY:
SA_NEXT_ID_LIST_ENTRY(ASP[1], ASP[2]);
ASC_PROCESS_ID:
SA_PROCESS_ID(ASP[1], ASP[2]);

{-- ASC_PROCESS_LABEL_DECLARATION_PART:
SA_PROCESS_LABEL_DECLARATION_PART(ASP[1]);
ASC_START_LABEL_LIST:
SA_START_LABEL_LIST(ASP[1], ASP[2]);
ASC_NEXT_LABEL_LIST_ENTRY:
SA_NEXT_LABEL_LIST_ENTRY(ASP[1], ASP[2]);
ASC_PROCESS_LABEL:
SA_PROCESS_LABEL(ASP[1], ASP[2]);--}

ASC_PROCESS_CONSTANT_DEFINITION:
SA_PROCESS_CONSTANT_DEFINITION(ASP[1], ASP[2], ASP[3]);
ASC_PROCESS_CONSTANT:
SA_PROCESS_CONSTANT(ASP[1], ASP[2]);

{-- ASC_PROCESS_FIGURATIVE_CONST:
SA_PROCESS_FIGURATIVE_CONST(ASP[1], ASP[2]);--}

ASC_PROCESS_BOOLEAN_CONST:
SA_PROCESS_BOOLEAN_CONST(ASP[1], ASP[2]);
ASC_PROCESS_SIGNED_NUMBER:
SA_PROCESS_SIGNED_NUMBER(ASP[1], ASP[2], ASP[3]);
ASC_PROCESS_UNSIGNED_NUMERIC_CONST:
SA_PROCESS_UNSIGNED_NUMERIC_CONST(ASP[1], ASP[2]);
ASC_PROCESS_INTEGER_CONST:
SA_PROCESS_INTEGER_CONST(ASP[1], ASP[2]);
ASC_PROCESS_REAL_CONST:
SA_PROCESS_REAL_CONST(ASP[1], ASP[2]);
ASC_PROCESS_CONSTANT_ID:
SA_PROCESS_CONSTANT_ID(ASP[1], ASP[2]);
ASC_PROCESS_SIGNED_NUMERIC_CONST:
SA_PROCESS_SIGNED_NUMERIC_CONST(ASP[1], ASP[2], ASP[3]);
ASC_PROCESS_SIGN:
SA_PROCESS_SIGN(ASP[1], ASP[2]);
ASC_PROCESS_TEXT_STRING:
SA_PROCESS_TEXT_STRING(ASP[1], ASP[2]);
ASC_PROCESS_STRING_CONST:
SA_PROCESS_STRING_CONST(ASP[1], ASP[2]);

{-- ASC_PROCESS_CONTROL_CHAR:
SA_PROCESS_CONTROL_CHAR(ASP[1], ASP[2]);--}

ASC_PROCESS_TYPE_DEFINITION:
SA_PROCESS_TYPE_DEFINITION(ASP[1], ASP[2]);
ASC_PROCESS_SCALAR_TYPE:
SA_PROCESS_SCALAR_TYPE(ASP[1], ASP[2]);

{-- ASC_PROCESS_SUBRANGE_TYPE_DESIGNATOR:
SA_PROCESS_SUBRANGE_TYPE_DESIGNATOR(ASP[1], ASP[2]);--}

ASC_PROCESS_RANGE_TYPE:
SA_PROCESS_RANGE_TYPE(ASP[1]);
ASC_PROCESS_TYPE_IDENTIFIER:
SA_PROCESS_TYPE_IDENTIFIER(ASP[1], ASP[2]);

{-- ASC_PROCESS_PACKED_STRUCTURED_TYPE:
SA_PROCESS_PACKED_STRUCTURED_TYPE(ASP[1], ASP[2]);--}

ASC_PROCESS_STRING_TYPE:
SA_PROCESS_STRING_TYPE(ASP[1], ASP[2]);

{-- ASC_PROCESS_STRING_SIZE_ALLOCATION:
SA_PROCESS_STRING_SIZE_ALLOCATION(ASP[1], ASP[2]);
ASC_PROCESS_ARRAY_TYPE:
SA_PROCESS_ARRAY_TYPE(ASP[1], ASP[2], ASP[3]);
ASC_START_INDEX_TYPE_LIST:
SA_START_INDEX_TYPE_LIST(ASP[1], ASP[2]);
ASC_NEXT_INDEX_TYPE_LIST_ENTRY:
SA_NEXT_INDEX_TYPE_LIST_ENTRY(ASP[1], ASP[2]);
ASC_START_RECORD_TYPE:
SA_START_RECORD_TYPE(ASP[1]);
ASC_NEXT_RECORD_SECTION:
SA_NEXT_RECORD_SECTION(ASP[1], ASP[2], ASP[3]);
ASC_START_FIELD_IDENTIFIER_LIST:
SA_START_FIELD_IDENTIFIER_LIST(ASP[1], ASP[2]);
ASC_NEXT_FIELD_IDENTIFIER_LIST_ENTRY:
SA_NEXT_FIELD_IDENTIFIER_LIST_ENTRY(ASP[1], ASP[2]);
ASC_START_VARIENT_LIST:
SA_START_VARIENT_LIST(ASP[1], ASP[2]);
ASC_NEXT_VARIENT_LIST_ENTRY:
SA_NEXT_VARIENT_LIST_ENTRY(ASP[1], ASP[2]);
ASC_PROCESS_VARIENT:
SA_PROCESS_VARIENT(ASP[1], ASP[2], ASP[3]);
ASC_START_CASE_LABEL_LIST:
SA_START_CASE_LABEL_LIST(ASP[1], ASP[2]);
ASC_NEXT_CASE_LABEL_LIST_ENTRY:
SA_NEXT_CASE_LABEL_LIST_ENTRY(ASP[1], ASP[2]);--}

ASC_PROCESS_SET_TYPE:
SA_PROCESS_SET_TYPE(ASP[1], ASP[2]);

{-- ASC_PROCESS_FILE_TYPE:
SA_PROCESS_FILE_TYPE(ASP[1], ASP[2]);
ASC_PROCESS_POINTER_TYPE:
SA_PROCESS_POINTER_TYPE(ASP[1], ASP[2]);--}

ASC_PROCESS_VARIABLE_DECLARATION:
SA_PROCESS_VARIABLE_DECLARATION(ASP[1], ASP[2]);

{-- ASC_PROCESS_PARAMETER_GROUP:
SA_PROCESS_PARAMETER_GROUP(ASP[1], ASP[2], ASP[3]);
ASC_PROCESS_PROCEDURE_CALL:
SA_PROCESS_PROCEDURE_CALL(ASP[1], ASP[2]);
ASC_PROCESS_ASSIGNMENT_OPERATION:
SA_PROCESS_ASSIGNMENT_OPERATION(ASP[1], ASP[2]);
ASC_PROCESS_PREDEFINED_MEMORY_ARRAY_REF:
SA_PROCESS_PREDEFINED_MEMORY_ARRAY_REF(ASP[1], ASP[2], ASP[3], ASP[4]);
ASC_PROCESS_PREDEFINED_PORT_ARRAY_REF:
SA_PROCESS_PREDEFINED_PORT_ARRAY_REF(ASP[1], ASP[2], ASP[3]);
ASC_PROCESS_ARRAY_SUBSCRIPTS_REF:
SA_PROCESS_ARRAY_SUBSCRIPTS_REF(ASP[1], ASP[2]);
ASC_PROCESS_POINTER_REFERENCE:
SA_PROCESS_POINTER_REFERENCE(ASP[1]);
ASC_START_ARRAY_SUBSCRIPT_LIST:
SA_START_ARRAY_SUBSCRIPT_LIST(ASP[1], ASP[2]);
ASC_NEXT_ARRAY_SUBSCRIPT_LIST_ENTRY:
SA_NEXT_ARRAY_SUBSCRIPT_LIST_ENTRY(ASP[1], ASP[2]);
ASC_PROCESS_FIELD_REF:
SA_PROCESS_FIELD_REF(ASP[1], ASP[2]);
ASC_PROCESS_SYSTEM_VARIABLE:
SA_PROCESS_SYSTEM_VARIABLE(ASP[1], ASP[2]);
ASC_PROCESS_INFIX_OPERATION:
SA_PROCESS_INFIX_OPERATION(ASP[1], ASP[2], ASP[3], ASP[4]);
ASC_PROCESS_RELATIONAL_OPERATOR:
SA_PROCESS_RELATIONAL_OPERATOR(ASP[1], ASP[2]);
ASC_PROCESS_ADDING_OPERATOR:
SA_PROCESS_ADDING_OPERATOR(ASP[1], ASP[2]);
ASC_PROCESS_MULTIPLYING_OPERATOR:
SA_PROCESS_MULTIPLYING_OPERATOR(ASP[1], ASP[2]);
ASC_PROCESS_UNARY_NOT_OPERATION:
SA_PROCESS_UNARY_NOT_OPERATION(ASP[1], ASP[2]);
ASC_PROCESS_UNARY_SIGN_OPERATION:
SA_PROCESS_UNARY_SIGN_OPERATION(ASP[1], ASP[2], ASP[3]);
ASC_PROCESS_SET_CONSTRUCTOR:
SA_PROCESS_SET_CONSTRUCTOR(ASP[1], ASP[2]);
ASC_START_SET_ELEMENT_LIST:
SA_START_SET_ELEMENT_LIST(ASP[1], ASP[2]);
ASC_NEXT_SET_ELEMENT_LIST_ENTRY:
SA_NEXT_SET_ELEMENT_LIST_ENTRY(ASP[1], ASP[2]);
ASC_PROCESS_SET_ELEMENT_RANGE_BEGINNNG:
SA_PROCESS_SET_ELEMENT_RANGE_BEGINNNG(ASP[1], ASP[2]);
ASC_PROCESS_SET_ELEMENT_RANGE_ENDING:
SA_PROCESS_SET_ELEMENT_RANGE_ENDING(ASP[1], ASP[2]);
ASC_PROCESS_ACTUAL_PROC_OR_FUNC_PARAM_LIST:
SA_PROCESS_ACTUAL_PROC_OR_FUNC_PARAM_LIST(ASP[1], ASP[2]);
ASC_START_ACTUAL_PROC_OR_FUNC_PARAM_LIST:
SA_START_ACTUAL_PROC_OR_FUNC_PARAM_LIST(ASP[1], ASP[2]);
ASC_NEXT_ACTUAL_PROC_OR_FUNC_PARAM_LIST_ENTRY:
SA_NEXT_ACTUAL_PROC_OR_FUNC_PARAM_LIST_ENTRY(ASP[1], ASP[2]);
ASC_PROCESS_GOTO_STMT:
SA_PROCESS_GOTO_STMT(ASP[1]);
ASC_PROCESS_INLINE_STMT:
SA_PROCESS_INLINE_STMT(ASP[1]);
ASC_START_INLINE_ELEMENT_LIST:
SA_START_INLINE_ELEMENT_LIST(ASP[1], ASP[2]);
ASC_NEXT_INLINE_ELEMENT_LIST_ENTRY:
SA_NEXT_INLINE_ELEMENT_LIST_ENTRY(ASP[1], ASP[2]);
ASC_PROCESS_INLINE_LIST_ELEMENT_ID:
SA_PROCESS_INLINE_LIST_ELEMENT_ID(ASP[1], ASP[2]);
ASC_PROCESS_LOCATION_COUNTER_REF:
SA_PROCESS_LOCATION_COUNTER_REF(ASP[1], ASP[2]);
ASC_PROCESS_SIGNED_LOCATION_COUNTER_OFFSET:
SA_PROCESS_SIGNED_LOCATION_COUNTER_OFFSET(ASP[1], ASP[2], ASP[3]);
ASC_START_IF:
SA_START_IF(ASP[1]);
ASC_IF_TEST:
SA_IF_TEST(ASP[1], ASP[2]);
ASC_GEN_OUT_LABEL:
SA_GEN_OUT_LABEL(ASP[1]);
ASC_GEN_JUMP:
SA_GEN_JUMP;
ASC_GEN_ELSE_LABEL:
SA_GEN_ELSE_LABEL(ASP[1], ASP[2]);
ASC_START_CASE_ELEMENT_LIST:
SA_START_CASE_ELEMENT_LIST(ASP[1], ASP[2]);
ASC_NEXT_CASE_ELEMENT_LIST_ENTRY:
SA_NEXT_CASE_ELEMENT_LIST_ENTRY(ASP[1], ASP[2]);
ASC_START_RECORD_VARIABLE_LIST:
SA_START_RECORD_VARIABLE_LIST(ASP[1], ASP[2]);
ASC_NEXT_RECORD_VARIABLE_LIST_ENTRY:
SA_NEXT_RECORD_VARIABLE_LIST_ENTRY(ASP[1], ASP[2]);
ASC_PROCESS_STD_INPUT_PROCEDURE_CALL:
SA_PROCESS_STD_INPUT_PROCEDURE_CALL(ASP[1], ASP[2]);
ASC_START_STD_INPUT_PROCEDURE_PARAM_LIST:
SA_START_STD_INPUT_PROCEDURE_PARAM_LIST(ASP[1], ASP[2]);
ASC_NEXT_STD_INPUT_PROCEDURE_PARAM_LIST_ENTRY:
SA_NEXT_STD_INPUT_PROCEDURE_PARAM_LIST_ENTRY(ASP[1], ASP[2]);
ASC_PROCESS_STD_OUTPUT_PROCEDURE_CALL:
SA_PROCESS_STD_OUTPUT_PROCEDURE_CALL(ASP[1], ASP[2]);
ASC_PROCESS_STD_OUTPUT_PROCEDURE_PARAM_ELEMENT:
SA_PROCESS_STD_OUTPUT_PROCEDURE_PARAM_ELEMENT(ASP[1], ASP[2], ASP[3]);
ASC_PROCESS_STD_OUTPUT_FIELD_WIDTH_SPEC:
SA_PROCESS_STD_OUTPUT_FIELD_WIDTH_SPEC(ASP[1], ASP[2]);
ASC_PROCESS_STD_OUTPUT_FIELD_DECIMAL_PLACES_SPEC:
SA_PROCESS_STD_OUTPUT_FIELD_DECIMAL_PLACES_SPEC(ASP[1], ASP[2]);
ASC_PROCESS_STANDARD_ARITHMETIC_FUNCTION_REF:
SA_PROCESS_STANDARD_ARITHMETIC_FUNCTION_REF(ASP[1], ASP[2], ASP[3]);
ASC_PROCESS_STANDARD_SCALAR_FUNCTION_REF:
SA_PROCESS_STANDARD_SCALAR_FUNCTION_REF(ASP[1], ASP[2], ASP[3]);
ASC_PROCESS_STANDARD_TRANSFER_FUNCTION_REF:
SA_PROCESS_STANDARD_TRANSFER_FUNCTION_REF(ASP[1], ASP[2], ASP[3]);
ASC_PROCESS_DELETE_STD_STRING_PROCEDURE_CALL:
SA_PROCESS_DELETE_STD_STRING_PROCEDURE_CALL(ASP[1], ASP[2], ASP[3]);
ASC_PROCESS_INSERT_STD_STRING_PROCEDURE_CALL:
SA_PROCESS_INSERT_STD_STRING_PROCEDURE_CALL(ASP[1], ASP[2], ASP[3]);
ASC_PROCESS_STR_STD_STRING_PROCEDURE_CALL:
SA_PROCESS_STR_STD_STRING_PROCEDURE_CALL(ASP[1], ASP[2]);
ASC_PROCESS_VAL_STD_STRING_PROCEDURE_CALL:
SA_PROCESS_VAL_STD_STRING_PROCEDURE_CALL(ASP[1], ASP[2], ASP[3]);
ASC_PROCESS_STD_STRING_FUNCTION:
SA_PROCESS_STD_STRING_FUNCTION;
ASC_PROCESS_CONCAT_STD_STRING_FUNCTION_REF:
SA_PROCESS_CONCAT_STD_STRING_FUNCTION_REF(ASP[1], ASP[2]);
ASC_PROCESS_COPY_STD_STRING_FUNCTION_REF:
SA_PROCESS_COPY_STD_STRING_FUNCTION_REF(ASP[1], ASP[2], ASP[3], ASP[4]);
ASC_PROCESS_LENGTH_STD_STRING_FUNCTION_REF:
SA_PROCESS_LENGTH_STD_STRING_FUNCTION_REF(ASP[1], ASP[2]);
ASC_PROCESS_POS_STD_STRING_FUNCTION_REF:
SA_PROCESS_POS_STD_STRING_FUNCTION_REF(ASP[1], ASP[2], ASP[3]);
ASC_START_STRING_EXPRESSION_LIST:
SA_START_STRING_EXPRESSION_LIST(ASP[1], ASP[2]);
ASC_NEXT_STRING_EXPRESSION_LIST_ENTRY:
SA_NEXT_STRING_EXPRESSION_LIST_ENTRY(ASP[1], ASP[2]);
ASC_PROCESS_BLOCK_RW_RETURN_RESULT:
SA_PROCESS_BLOCK_RW_RETURN_RESULT;
ASC_PROCESS_MAXAVAIL_STD_HEAP_CONTROL_FUNCTION:
SA_PROCESS_MAXAVAIL_STD_HEAP_CONTROL_FUNCTION(ASP[1]);
ASC_PROCESS_MEMAVAIL_STD_HEAP_CONTROL_FUNCTION:
SA_PROCESS_MEMAVAIL_STD_HEAP_CONTROL_FUNCTION(ASP[1]);
ASC_PROCESS_PTR_STD_HEAP_CONTROL_FUNCTION:
SA_PROCESS_PTR_STD_HEAP_CONTROL_FUNCTION(ASP[1], ASP[2]);
ASC_PROCESS_QUASI_STD_SCREEN_RELATED_PROCEDURE_CALL:
SA_PROCESS_QUASI_STD_SCREEN_RELATED_PROCEDURE_CALL(ASP[1]);
ASC_PROCESS_GOTOXY_QUASI_STD_SCREEN_RELATED_PROCEDURE_CALL:
SA_PROCESS_GOTOXY_QUASI_STD_SCREEN_RELATED_PROCEDURE_CALL(ASP[1],
ASP[2]);
ASC_PROCESS_QUASI_STD_SCREEN_RELATED_FUNCTION_REF:
SA_PROCESS_QUASI_STD_SCREEN_RELATED_FUNCTION_REF(ASP[1], ASP[2]);
ASC_PROCESS_FILLCHAR_QUASI_STD_MISC_PROCEDURE_CALL:
SA_PROCESS_FILLCHAR_QUASI_STD_MISC_PROCEDURE_CALL(ASP[1], ASP[2],
ASP[3]);
ASC_PROCESS_QUASI_STD_MISC_PROCEDURE_CALL:
SA_PROCESS_QUASI_STD_MISC_PROCEDURE_CALL(ASP[1]);
ASC_PROCESS_DELAY_QUASI_STD_MISC_PROCEDURE_CALL:
SA_PROCESS_DELAY_QUASI_STD_MISC_PROCEDURE_CALL(ASP[1]);
ASC_PROCESS_MOVE_QUASI_STD_MISC_PROCEDURE_CALL:
SA_PROCESS_MOVE_QUASI_STD_MISC_PROCEDURE_CALL(ASP[1], ASP[2], ASP[3]);
ASC_PROCESS_QUASI_STD_MISC_FUNCTION_REF:
SA_PROCESS_QUASI_STD_MISC_FUNCTION_REF(ASP[1], ASP[2], ASP[3]);
ASC_PROCESS_PARAMETERLESS_QUASI_STD_MISC_FUNCTION_REF:
SA_PROCESS_PARAMETERLESS_QUASI_STD_MISC_FUNCTION_REF(ASP[1], ASP[2]);
ASC_PROCESS_RANDOM_QUASI_STD_MISC_FUNCTION_REF:
SA_PROCESS_RANDOM_QUASI_STD_MISC_FUNCTION_REF(ASP[1], ASP[2]);
ASC_PROCESS_INTEGER_UPPER_RAMDOM_LIMIT:
SA_PROCESS_INTEGER_UPPER_RAMDOM_LIMIT(ASP[1], ASP[2]);
ASC_PROCESS_REAL_RANDOM_LIMIT:
SA_PROCESS_REAL_RANDOM_LIMIT(ASP[1], ASP[2]);
ASC_CHECK_IF_TYPE_IS_STRING:
SA_CHECK_IF_TYPE_IS_STRING(ASP[1], ASP[2]);
ASC_CHECK_IF_TYPE_IS_SCALAR:
SA_CHECK_IF_TYPE_IS_SCALAR(ASP[1], ASP[2]);
ASC_CHECK_IF_TYPE_IS_SCALAR_OR_POINTER:
SA_CHECK_IF_TYPE_IS_SCALAR_OR_POINTER(ASP[1], ASP[2]);
ASC_CHECK_IF_TYPE_IS_INTEGER:
SA_CHECK_IF_TYPE_IS_INTEGER(ASP[1], ASP[2]);
ASC_CHECK_IF_TYPE_IS_REAL:
SA_CHECK_IF_TYPE_IS_REAL(ASP[1], ASP[2]);
ASC_CHECK_IF_TYPE_IS_REAL_OR_INTEGER:
SA_CHECK_IF_TYPE_IS_REAL_OR_INTEGER(ASP[1], ASP[2]);
ASC_CHECK_IF_BASE_TYPE_IS_UNTYPED:
SA_CHECK_IF_BASE_TYPE_IS_UNTYPED(ASP[1], ASP[2]);
ASC_CHECK_IF_BASE_TYPE_IS_TEXT:
SA_CHECK_IF_BASE_TYPE_IS_TEXT(ASP[1], ASP[2]);
ASC_CHECK_IF_TYPE_IS_FILE:
SA_CHECK_IF_TYPE_IS_FILE(ASP[1], ASP[2]);
ASC_CHECK_IF_POINTER_VARIABLE:
SA_CHECK_IF_POINTER_VARIABLE(ASP[1], ASP[2]);
ASC_CHECK_IF_TYPE_IS_BOOLEAN:
SA_CHECK_IF_TYPE_IS_BOOLEAN(ASP[1], ASP[2]);
ASC_CHECK_IF_TYPE_IS_CHAR_OR_BYTE:
SA_CHECK_IF_TYPE_IS_CHAR_OR_BYTE(ASP[1], ASP[2]);
ASC_CHECK_IF_VARIABLE_OR_TYPE_IDENTIFIER:
SA_CHECK_IF_VARIABLE_OR_TYPE_IDENTIFIER(ASP[1], ASP[2]);
ASC_CHECK_IF_TYPE_IS_CHAR:
SA_CHECK_IF_TYPE_IS_CHAR(ASP[1], ASP[2]);--}

ASC_FINISH_PROGRAM:
SA_FINISH_PROGRAM;
ASC_START_PROGRAM:
SA_START_PROGRAM;

(*------------------------------------------------------------------------*)
(**************************************************************************)

ELSE PROCESS_UNIMPLIMENTED_SEMANTIC_ACTION_REQUEST;
END; (* END OF CASE *)
END;

(**************************************************************************)
(* THIS IS END OF A SEMANTIC ACTION DISPATCH FILE FOR LL(1) PARSER *)
(**************************************************************************)

Lieven Marchand

unread,
Mar 6, 2000, 3:00:00 AM3/6/00
to
pwa...@my-deja.com writes:

> I've also heard that some languages have experimented with permitting
> n-ary comparisons (eg, "1 < x < 10" instead of "x > 1 && x < 10", but
> they always conclude that its a mistake. Hard to understand code gets
> produced, and I think there's a parsing problem, but I forget what.

Common Lisp does exactly that.

Your example would become:

(< 1 x 10)

As usual, fully parenthesised prefix notation kills the parsing problem.

About the only catch for beginners are the values of

(= 1) and (/= 1).

Carles Blas Anglada

unread,
Mar 6, 2000, 3:00:00 AM3/6/00
to
John Fremlin wrote:

> Has any programming language/compiler implemented pronoun like

> constructs? For example:
>
> if variable_with_long_name == '2 ,
> { do this; }
> if it == '3 , # equivalent to: variable_with_long_name == '3
> { do that }
>

Apart from a nice theoretical discussion. Why does anybody need it? (Or why
does anybody need pronouns?). In your example there is an elegant
construction that answers that question: switch.

switch (variable_with_long_name)
case 2: do_this; break;
case 3: do_that;

Ben Zorn

unread,
Mar 6, 2000, 3:00:00 AM3/6/00
to
Todd Proebsting and I have written a tech report describing a number
of possible programming shorthands (including pronouns). The TR is
available at:
http://research.microsoft.com/scripts/pubs/view.asp?TR_ID=MSR-TR-2000-03

For example, we propose a pronoun that abbreviates the following:

a.b.c.d.e = x+y;
a.b.c.d.f = x+z;

as:

(a.b.c.d).e = x+y;
$().f = x+z;

where $() is the pronoun referring to the last parenthesized expression.

-Ben Zorn


Norman Ramsey

unread,
Mar 6, 2000, 3:00:00 AM3/6/00
to
<pwa...@my-deja.com> wrote:
>I've also heard that some languages have experimented with permitting
>n-ary comparisons (eg, "1 < x < 10" instead of "x > 1 && x < 10", but
>they always conclude that its a mistake. Hard to understand code gets
>produced, and I think there's a parsing problem, but I forget what.

Icon does this beautifully, but its model of Booleans is
success/failure, not true/false. www.cs.arizona.edu/icon

Martin Neitzel

unread,
Mar 6, 2000, 3:00:00 AM3/6/00
to
John Fremlin <v...@altern.org> writes:
JF>
JF> Has any programming language/compiler implemented pronoun like
JF> constructs? For example:

The "J" programming language has a grammar defined in terms of "nouns",
"verbs", "adverbs", "conjunctions", "gerunds", "sentences", and "phrasal
forms". Adverbs and conjunctions are higher-order functionals applying
to one or two verbs (i.e., functions), respectively. It's amazing how
flexible it is syntactly, and it is also amazing how satisfying it is
to escape from the old rigid subject-predicate-object straight-jacket
most other langages force upon us poor programmers.

More specific to the original question on pronouns:

J has various "phrasal forms" which are implicit combinators. The "Hook"
form provides essentially possessive pronouns:

(+ %) 4 NB. input expression
4.25 NB. result: 4 plus *its* reciprocal

As you can see, an isolated function group forms not just a plain pipeline
function, but some more hideous data flow setup. The rules are simple,
though. Common experience of all J programmers is:

"First you wonder if you'd ever have use for these constructs --
but then you slowly but surely recognize that they are EVERYWHERE."

Academic plug: Kenneth E. Iverson et al.: "The Dictionary of J", 1990 1st
edition, has been roughly yearly revised, along with the implementation.
Yes, that's the APL Iverson, and yes, J sure groks arrays (but not greek
symbols, phew ;-) And no, there's no "ava" behind this J.

Commercial/informational/evaluational/in-depth plug: go to
http://www.jsoftware.com/ for more info. Supported platforms are MS
Windows, MacOS, various Unixens, and, of course: Your Mind.

Ob. comp.compilers: Sorry, J has the the evil eval primitive. Other than
that, compiling J is a great project for a compiler construction class.
Tokenization and parsing are very simple, and students can really get
to the business of good code generation with this language.

Martin Neitzel

Joachim Durchholz

unread,
Mar 6, 2000, 3:00:00 AM3/6/00
to
Carles Blas Anglada <carle...@uab.es> schrieb in im Newsbeitrag:

> In your example there is an elegant
> construction that answers that question: switch.
>
> switch (variable_with_long_name)
> case 2: do_this; break;
> case 3: do_that;

Pascal has

with <some path expression that returns a struct lvalue> do
begin
<some statements where struct members can be
accessed without repeating the above path expression>
end

BTW this is related to variable binding with call-by-reference
parameters:

procedure do_something (var foo: whatever)
(* People with a C background, assume 'whatever *foo'. *)
begin
...
end

do_something (some-exceedingly-long-path-expression)

Call-by-reference is probably the reason why most languages don't have
pronouns. Call-by-reference is much less dependent on context, i.e.
rearranging statements or even nesting doesn't inadvertently affect the
meaning of a call-by-reference parameter, while the mechanisms listed so
far in this group are all sensitive to such changes. Of course, if you
write a procedure just to get rid of some exceedingly long path name,
you there's a syntactic overhead to pay, and more than what the other
mechanisms require.

Regards,
Joachim

Ralph Corderoy

unread,
Mar 11, 2000, 3:00:00 AM3/11/00
to
Hi,

> I've also heard that some languages have experimented with permitting
> n-ary comparisons (eg, "1 < x < 10" instead of "x > 1 && x < 10", but
> they always conclude that its a mistake. Hard to understand code
> gets produced, and I think there's a parsing problem, but I forget
> what.

A `mainstream' language that provides this is Python, www.python.org.

>>> a, b, c = 3, 6, 1
>>> a < b < c
0
>>> a < b > c
1
>>> a < b != c
1
>>> (a < b) != c
0


Ralph.

Gene Wirchenko

unread,
Mar 21, 2000, 3:00:00 AM3/21/00
to
>> COBOL also has condition names which in effect allow elision of
>> subject field name and relational! The condition name feature includes
>> ranges and list of values. You can code something like
>
>
>COBOL also has the MOVE CORRESPONDING verb to move data
>with the same field name between records, which is pronoun-like.

Similarly, PL/I has the BY NAME clause when assigning to a
structure from another structure.

Sincerely,

Gene Wirchenko

0 new messages