And no, I am not seriously suggesting it myself, but I would be
interested in any history of debate on the issue if it were ever
proposed.
--
Jack Klein
Home: http://JK-Technology.Com
Jack Klein wrote:
>
> Just wondering if anyone ever suggested adding Perl's unless (antonym
> for if) and until (antonym for while) keywords to C.
>
> And no, I am not seriously suggesting it myself, but I would be
> interested in any history of debate on the issue if it were ever
> proposed.
BCPL had 'unless' and 'until' as well as the if and while.
Lost in B and thereafter in C. Like gills in mammals, perhaps.
Dennis
#define unless(expr) if(!(expr))
#define until(expr) while(!(expr))
zw
|> Just wondering if anyone ever suggested adding Perl's unless (antonym
|> for if) and until (antonym for while) keywords to C.
What wrong with
#define unless(C) if (!(C))
#define until(C) while (!(C))
?
Andreas.
--
Andreas Schwab "And now for something
Andreas...@suse.de completely different."
SuSE Labs, SuSE GmbH, Schanzäckerstr. 10, D-90443 Nürnberg
Key fingerprint = 58CA 54C7 6D53 942B 1756 01D3 44D5 214B 8276 4ED5
Very wrong (if you want something similar to Perl).
In Perl you can write "<statement> unless <condition>"; yours would be
"unless <condition> <statement>".
There is no such thing as "<statement> if <condition>" in C either, so you
can't compare that.
Oh, but this is a different issue. This use of unless (or if) in Perl is
more akin to short-circuit operator (like &&, || and ?: in C), for
example it doesn't require parentheses arount the condition expression.
It is independent from the C-like use of if/unless in Perl.
Whether C lacks unless (i.e. a negation to if) and whether it lacks an
postfix version of if/unless are two orthogonal issues.
I often wish C had such postfix if/unless, because some code is just
much more clearer with the action in front and the condition behind.
-- Niklas Matthies
--
There is no such thing as luck. Luck is nothing but an absence of bad luck.
My experience is that they were fairly heavily used (say 20% of
the uses of the corresponding positive), but were not missed
much by people moving from BCPL to other languages. As other
people have pointed out, adding a negation and some brackets is
not a big deal, and can trivially be automated.
What was missed, badly, as people changed languages was Algol
68's unit concept. In C terms, this would have the syntax:
while <statement sequence> do <statement sequence> od
where the last statement in the first statement sequence
evaluated to the condition. This is a MUCH more powerful
paradigm, and eliminates a lot of messy flags indicating
that a pass is first time through. The similar construct for
the if statement enabled much cleaner scoping without adding
unecessary levels.
But it really doesn't fit into C or BCPL, the C99 extensions
to the for statement notwithstanding.
Regards,
Nick Maclaren,
University of Cambridge Computing Service,
New Museums Site, Pembroke Street, Cambridge CB2 3QG, England.
Email: nm...@cam.ac.uk
Tel.: +44 1223 334761 Fax: +44 1223 334679
Lack of standardization. Many people think that keyword rewriting is bad,
and don't like learning somebody else's nonstandard syntax. If unless and
until are frequently used, they should be part of the language.
Ever see the old Bourne shell code?
(This opinion is not unanimous -- the C++ committee decided not to add a
keyword to represent the base class type in a derived class after someone
demonstrated that a typedef could be used to the same effect.)
--
John Carr (j...@mit.edu)
(raises hand)
Missed *dreadfully* by some people; an explicit negation can make
the condition much less readable. Thank the stars that Pop11 has
unless and until.
--
Chris "electric hedgehog" Dollin
C FAQs at: http://www.faqs.org/faqs/by-newsgroup/comp/comp.lang.c.html
Could you give an example? If you read the negation as "not", in my
experience it usually is quite readable.
I have seen this claim many times before, and can believe that
it may be true for a few people. I find it surprising that they
can't learn such a minor variation, but human language handling
is very weird. Such people claim that the first of the following
constructions is comprehensible and the latter is not:
UNLESS (condition) statement
IF (NOT (condition)) statement
I find it fractionally easier to read the second, but (like most
people) am happy with either. In general, I am less happy with:
UNLESS (NOT (condition)) statement
[...re: "unless(cond) more readable than if(not cond)...]
>I have seen this claim many times before, and can believe that
>it may be true for a few people. I find it surprising that they
>can't learn such a minor variation, but human language handling
>is very weird. Such people claim that the first of the following
>constructions is comprehensible and the latter is not:
>
> UNLESS (condition) statement
> IF (NOT (condition)) statement
The latter can be difficult if "condition" is quite complex.
De Morgan's laws can be applied, but if "condition" is complex, the
potential for errors is significant, and the result may be no clearer.
When faced with this situation in the past, I have often resorted to
if (<complex condition>)
{
/* do nothing. Explain why. */
}
else
{
/* etc. */
}
I find this more "comprehensible" than I would an "unless" keyword,
but that is just MHO. In any case, every compiler I've tried this on
generates nearly identical code to that when given
if (!(<complex condition>))
{
/* etc. */
}
Regards,
-=Dave
--
Change is inevitable, progress is not.
Yes, but De Morgan's laws need to be applied to the first just
as much as the second - after all, those constructions are
SEMANTICALLY equivalent!
|> When faced with this situation in the past, I have often resorted to
|>
|> if (<complex condition>)
|> {
|> /* do nothing. Explain why. */
|> }
|> else
|> {
|> /* etc. */
|> }
|>
|> I find this more "comprehensible" than I would an "unless" keyword,
|> but that is just MHO. ...
In extremis, I have resorted to:
IF (<complex condition>)
IF ((<complex condition>) OR (<complex condition>))
statement
and similar. But this is a different issue, and orthogonal to
whether UNLESS if clearer than IF NOT.
as did Algol 68, where the construct was:
FOR i FROM f BY b TO t WHILE w DO statements OD
Any or all of the prefixes could be omitted, so that:
FROM 5 WHILE w DO statements OD
was legal.
--
Clive D.W. Feather, writing for himself | Home: <cl...@davros.org>
Tel: +44 20 8371 1138 (work) | Web: <http://www.davros.org>
Fax: +44 20 8371 4037 (D-fax) | Work: <cl...@demon.net>
Written on my laptop; please observe the Reply-To address
There has been a considerable amount of research that suggests that
negative statements are more error prone, and misunderstood than
positive one.
Francis Glassborow
I offer my sympathy and prayers to all those who are suffering
as a result of the events of September 11 2001.
I probably do not understand the construct, but doesn't replacing ';'
with ',' (sequence operators) provide the same semantics:
while(
x=3,
y=f(x),
/* etc */
x != y
){
/* actions */
Yes, but remember that the context of this is the claim that
UNLESS condition DO statement
is less clear than
IF NOT (condition) DO statement
Both are negative statements - in fact, they are semantically
identical.
Not if you want to use *statements* as well as *expressions* in the
preamble (and you do).
I think you mean "more clear". Certainly for me UNLESS is clearer than
IF NOT().
> Both are negative statements - in fact, they are semantically
> identical.
Certainly true. The *reason* for the subjective difference is hard
to identify (and not my field of expertise). I have a guesses.
IF NOT does not mean UNLESS unless the NOT negates the entire
condition. Because expressions such as
IF NOT spindizzy AND dirac THEN ...
exist, seeing an IF NOT doesn't immediately say "the entire condition
is negated"; it says "at least some of the condition is negated". So
an UNLESS gives "early warning" that it's the whole condition that is
negated.
Second-order effects:
In a language with both UNLESS and IF, one [for some value of "one"] can
expect that an IF NOT is *not* an UNLESS (ie there are ANDs and ORs
involved), otherwise why not *write* UNLESS?
If the language doesn't allow UNLESS conditions to have ELSE parts
(as in BCPL, but not Pop11, which allows essentially arbitrary mixing),
then an UNLESS also says "and do nothing otherwise".
--
Chris "putting UNLESS into languages I design" Dollin
I meant clearer, yes - thanks for the correction! For me, the
converse is true, but only slightly.
|> > Both are negative statements - in fact, they are semantically
|> > identical.
|>
|> Certainly true. The *reason* for the subjective difference is hard
|> to identify (and not my field of expertise). I have a guesses.
Agreed, and it's not mine, either.
|> IF NOT does not mean UNLESS unless the NOT negates the entire
|> condition. ...
Agreed. Hence the parentheses I inserted :-)
|> Second-order effects:
|>
|> In a language with both UNLESS and IF, one [for some value of "one"] can
|> expect that an IF NOT is *not* an UNLESS (ie there are ANDs and ORs
|> involved), otherwise why not *write* UNLESS?
One finds IF NOT clearer? Some people do.
|> If the language doesn't allow UNLESS conditions to have ELSE parts
|> (as in BCPL, but not Pop11, which allows essentially arbitrary mixing),
|> then an UNLESS also says "and do nothing otherwise".
Pretty marginal, but a point.
No, for two reasons: (a) the left operand of "," is an
expression, whereas that of ";" is a statement or declaration;
(b) associated with any semantic description is a "mindset";
in one case, the mindset is "condition, which may, as a special
case, be a sequence of expressions", and in the other it is
"compound statement, which may, as a special case, be an
expression".
Point (b) is not a "technical" semantic issue; but it is
important in practice, as it influences the way the standard is
written, the examples used, the way textbooks are written, and the
way students are taught to write the language. I suspect that
your example:
>while(
> x=3,
> y=f(x),
>/* etc */
> x != y
> ){
>/* actions */
>}
would, if perpetrated by a student, attract attention from the C
style police and the one-true-bracketing-style zealots, and would
very possibly lose marks in an exam; whereas it would seem normal
to someone brought up with "while (compound statement) statement"
syntax, or even better with Nick's closure syntax.
--
Andy Walker, School of MathSci., Univ. of Nott'm, UK.
a...@maths.nott.ac.uk
While I accept all the other comments, any examiner who marked someone
down for that, IMO, should be severely criticised. Of course most
examiners refuse to allow others to see their marks so they get away
with such things. Personally I maintain that exam scripts should always
be returned so that justice can be seen to be done (these days it would
not be hard to retain the original and return a photo-copy, at the very
least such should be available on request. The idea that anyone can
appeal against grade while being deprived of the single most important
piece of evidence has always stunk) Sorry, that is not about C but it
is time we started putting our houses in order.
> whereas it would seem normal
>to someone brought up with "while (compound statement) statement"
>syntax, or even better with Nick's closure syntax.
Yes.
A language I devised for BRL, "rayselect", was entirely expression
oriented; even what were nominally declarations had values.
We could almost retrofit that idea onto C without breaking anything,
and certainly it could be done in a new procedural language.
I might mark someone down for that, and not be afraid to stand by
the fact. Just because C allows something does not mean that it
should be encouraged, and good programming style is definitely a
criterion used in such examinations. There are at least the
following reasons that someone should have to have VERY good
reasons to use the comma operator at all in such a project:
It is a well-known source of confusion, especially to
people reading the C in a hurry. Even someone who knows about
it can mistake the difference between a comma as an operator and
as a list separator, especially given its bizarre precedence.
It is not ABSOLUTELY clear that the sequencing rules for
statements and the comma operator are identical. I have never
invented a reasonable example where they are different, but am
not convinced there isn't one, either.
It is MUCH harder to add 'directives' into an expression
than between statements, which is particularly relevant when
parallelising a program after initial debugging. But consider
also the CX_LIMITED_RANGE pragma.
For those reasons, and perhaps others, I would regard any use
of a comma operator without BOTH a very good reason AND a comment
saying why it is needed as poor style.
Looks a lot like the "generalized do-while statement" that I've proposed
a number of times (although never formally):
do /statement/ while ( /expression/ ) /statement/
(The current do-while statement is just the degenerate form where the
second statement is a null statement.)
-Larry Jones
I like maxims that don't encourage behavior modification. -- Calvin
That's just what it was, though even more general, as Andy Walker
points out :-)
The big trouble in languages like C is that it can be very confusing
without explicit termination of a statement sequence.
well, I disagree, but that is a matter of opinion.
> It is MUCH harder to add 'directives' into an expression
> than between statements, which is particularly relevant when
> parallelising a program after initial debugging. But consider
> also the CX_LIMITED_RANGE pragma.
this(), then(), that();
this(),
# pragma parallel
then(),
# pragma noparallel
that();
Not a problem of C.
Clearly, but the scope for confusion is a simple matter of fact
and observation. It is, after all, one of the FAQs on this group.
|> > It is MUCH harder to add 'directives' into an expression
|> > than between statements, which is particularly relevant when
|> > parallelising a program after initial debugging. But consider
|> > also the CX_LIMITED_RANGE pragma.
|>
|> this(), then(), that();
|>
|> this(),
|> # pragma parallel
|> then(),
|> # pragma noparallel
|> that();
|>
|> Not a problem of C.
I suggest that you look at the specification of the CX_LIMITED_RANGE
pragma and the OpenMP C specification. That won't work with either.
I would be very much in favor of such a retrofitting (for what it's worth).
-- Niklas Matthies
--
They called me mad, and I called them mad, and damn them, they outvoted me.
[...]
>Looks a lot like the "generalized do-while statement" that I've proposed
>a number of times (although never formally):
>
> do /statement/ while ( /expression/ ) /statement/
>
>(The current do-while statement is just the degenerate form where the
>second statement is a null statement.)
I assume, then, it works something like:
for(;;) { /statement/ if (!/expression/) break; /statement/}
? Just curious.
>I probably do not understand the construct, but doesn't replacing ';'
>with ',' (sequence operators) provide the same semantics:
No, because *anything* could be in the statement sequence. Loops. Case
statements. Even GOTO. It was a *statement sequence*.
Put in C terms, any statement other than expression statement is a void
expression. Therefore you don't need to distinguish between the comma
operator and the semicolon delimiter, so you use the latter for
everything:
C: (a++, b++)
Algol: (a++; b++)
For the same reason, you don't need a ?: operator, because you just
reuse IF:
C: x = q ? b : c;
Algol: x = IF q THEN b ELSE c FI; full form
x = (q | b | c); brief form
and you could equally well use CASE statements:
x = CASE i IN x, y, z OUT n ESAC;
x = (i | x, y, z | n);
and I could waffle on for hours ....
Pop11 and Lisp already behave that way (of course), and the language
Spice I co-designed after an idea of Dave Raggett's is expression
oriented: it has multiple-valued expressions (including a useful
treatment of loops).
So we can replace "could be done" by "has been done".
Not really. "Has been done" is the case only for languages that
were designed that way from the start; there are plenty of others.
I am not convinced that it would be possible to retrofit into C;
in fact, I am virtually certain that it wouldn't be.
The problems would arise with such delights as scoping, and in what
contexts declaration-like expressions would be valid; both of these
areas were already pretty confused in C90 and the latter at least
has got badly worse in C99. Consider the effect of including an
expression that is a declaration of a static function including the
keyword "extern" inside an arbitrary expression. Now think of that
arbitrary expression being inside sizeof or the size of an array
parameter ....
Yes, I KNOW that I have a nasty, perverse mind :-)
Well, yes. My last sentence was a response to
and certainly it could be done in a new procedural language
where I took "it" to mean "entirely expression oriented". Perhaps I should
have dissected more finely.
> I am not convinced that it would be possible to retrofit into C;
> in fact, I am virtually certain that it wouldn't be.
(shudders at the thought)
> The problems would arise with such delights as scoping, and in what
> contexts declaration-like expressions would be valid; both of these
> areas were already pretty confused in C90 and the latter at least
> has got badly worse in C99. Consider the effect of including an
> expression that is a declaration of a static function including the
> keyword "extern" inside an arbitrary expression. Now think of that
> arbitrary expression being inside sizeof or the size of an array
> parameter ....
Boring, boring. Consider instead the expression
0 && (auto int schroedingersCat)
and wonder if the cat exists afterwards.
> Yes, I KNOW that I have a nasty, perverse mind :-)
I'll see your NP mind and raise you "the right operand of an AND or OR
is a scope block".
--
Chris "left to right evaluation, except when it isn't" Dollin
I don't think that's a problem :-) The requirement is that the
cat should have no visible effect outside the scope that encloses
it, and therefore the question of its existence is purely
metaphysical :-)
I realise that I didn't describe my example carefully enough. I
meant to say a declaration of a static INLINE function including
the keyword "extern" inside an arbitrary expression. The point
being that the standard requires the properties of such a
declaration to 'leak' outside the scope which encloses it.
So, in that case, the existence of the cat ceases to be purely a
metaphysical question and becomes observable ....
|> > Yes, I KNOW that I have a nasty, perverse mind :-)
|>
|> I'll see your NP mind and raise you "the right operand of an AND or OR
|> is a scope block".
Oh, THAT would be easy enough to kludge up. The scope of any
declaration could be the expression immediately enclosing it,
unless that expression is a complete statement in which case it
would be as at present. Simple to define and not all THAT messy.
Not particularly USEFUL, but ....
UNLESS NOT (condition) DONOT statement
;-)
--
Stephen Baynes CEng MBCS Stephen...@soton.sc.philips.com
Philips Semiconductors Ltd
Southampton SO15 0DJ +44 (0)23 80316431
United Kingdom My views are my own.
ke...@hplb.hpl.hp.com wrote:
>
> In article <3BB0ABF8...@null.net>,
> "Douglas A. Gwyn" <DAG...@null.net> writes:
> > ke...@hplb.hpl.hp.com wrote:
> >> Not if you want to use *statements* as well as *expressions* in the
> >> preamble (and you do).
> >
> > A language I devised for BRL, "rayselect", was entirely expression
> > oriented; even what were nominally declarations had values.
> > We could almost retrofit that idea onto C without breaking anything,
> > and certainly it could be done in a new procedural language.
>
> Pop11 and Lisp already behave that way (of course), and the language
Perl and TCL also have all statements returning a value and you can do
things like an exec to use a statement in an expression.
I thought gcc had bodged in statement expresessions. Syntax something
like:
(( while (x) { x--; } ))
There are probably cleaner solutions while still keeping backwards compatability.
I worked something out once - but the details have escaped me.
"Clive D. W. Feather" wrote:
>
> In article <4liLlXA9...@ntlworld.com>, Francis Glassborow
> <francis.g...@ntlworld.com> writes
> >>What was missed, badly, as people changed languages was Algol
> >>68's unit concept. In C terms, this would have the syntax:
> >>
> >> while <statement sequence> do <statement sequence> od
>
> >I probably do not understand the construct, but doesn't replacing ';'
> >with ',' (sequence operators) provide the same semantics:
>
> No, because *anything* could be in the statement sequence. Loops. Case
> statements. Even GOTO. It was a *statement sequence*.
>
If I remember my Pascal syntax, and I think it also appled to Algol, ';'
is a statement separator. Unlike C where it is a (experssion) statement terminator.
For example in a Pascal block the last expression statement did not need a ';' after it.
However in C it is required as part of the statement.
begin
a = b;
c = d+1
end
vs
{
a = b;
c = d +1;
I have used languages with the COME FROM statement :-)
> Not really. "Has been done" is the case only for languages that
> were designed that way from the start; there are plenty of others.
> I am not convinced that it would be possible to retrofit into C;
> in fact, I am virtually certain that it wouldn't be.
GNU C allows to embed arbitrary statements in expressions:
({int i = foo(); while (i > 0) i -= bar(); baz();})
is an expression which returns the result of baz() after evaluation of
the preceding statements.
I agree that this syntax is somewhat ugly, but I'm convinced that
in languages like C there should be no syntactic distinction between
statements and expressions, and it would have been very easy to design
C without this distinction.
--
__("< Marcin Kowalczyk * qrc...@knm.org.pl http://qrczak.ids.net.pl/
\__/
^^ SYGNATURA ZASTĘPCZA
QRCZAK
Algol 68 had that - it is an old technology.
|> I agree that this syntax is somewhat ugly, but I'm convinced that
|> in languages like C there should be no syntactic distinction between
|> statements and expressions, and it would have been very easy to design
|> C without this distinction.
No, that is not the same thing. GNU C still has a very hard
distinction between statements and expressions, but allows a
way of encapsulating a statement as an expression. Removing
the distinction is a MUCH harder task.
Even with GNU C's simpler approach, think about my inline
function example, and weep ....
But one can always write a compound statement with proper indentation
to make it non-confusing.
Not necessarily. I didn't say that the value of a declaration
has to be the value of the object denoted by (the last) one of
its identifiers; it could just be always "true", for example.
Well, damn, that's true of whatever they write.
> ... I would regard any use
> of a comma operator without BOTH a very good reason AND a comment
> saying why it is needed as poor style.
The comma operator is typically used in macros that have a value:
#define GET_NEXT() (bufp >= bufend ? (FillBuf(), *bufp++) : *bufp++)
If a programmer thought a comment was needed for the above I would
dock him points!
Oh, yes, I assumed that you meant that. I was thinking of horrors
like that inline function example I mentioned, but there are a
fair number of things that would be pretty nasty to sort out in
the scoping area.
There are even more delights when an expression can evaluate to a
label, of course :-)
Yes, but I mean a very good reason why it could not be split into
two statements, which I regard as always the preferred form (when
appropriate). You have given an example below where there is such
a reason.
|> > ... I would regard any use
|> > of a comma operator without BOTH a very good reason AND a comment
|> > saying why it is needed as poor style.
|>
|> The comma operator is typically used in macros that have a value:
|> #define GET_NEXT() (bufp >= bufend ? (FillBuf(), *bufp++) : *bufp++)
|>
|> If a programmer thought a comment was needed for the above I would
|> dock him points!
I wouldn't! I would expect him to comment (a) the exact syntactic
nature of the macro he was defining and (b) the exact assumptions
he was making about sequence points! I can't think of a reasonable
use of it that does not need justification, though I agree that the
justification in this case is about the macro as a whole and not
the comma operator in particular.
And that is why candidates ought to be allowed to explain their answers.
What actually matters is that they understand what they are doing and
why they did it. A good examiner understands that their way is not
always the 'One True Way.'
That is very true, but I would NOT regard it as adequate in this
case. In particular, unless the programmer had commented in an
appropriate location on the consequences of GET_NEXT()+GET_NEXT(),
I would not be kind. And I wouldn't care if he hadn't used that
elsewhere in the code; it is a trap awaiting anyone who might
extend or maintain that program later.
And, yes, I HAVE been caught out by that trap myself :-(
Umm. I largely agree. For that reason, my personal practice
has for some years been instead to award bonus marks for *good* [in
my subjective view] style. In other words, I mark programs in the
"Arts" ["beta++?alpha-"] style, not the "Science" ["89/100"] style.
There is a "career grade" which you get for writing [and documenting,
testing, blah] a working program, and from there you go up for things
like good style, neat solutions, careful testing, etc., and down for
malfunctions of various sorts.
> Of course most
>examiners refuse to allow others to see their marks so they get away
>with such things. [...] Sorry, that is not about C but it
>is time we started putting our houses in order.
Many universities, inc this one, already practice double
marking and/or various forms of internal and external moderation,
not to mention "blind" marking and various modes of feedback. In
the UK, the data protection laws are starting to make us all think
about our practices wrt secrecy, return of scripts, etc; so your
concerns are being addressed. [Apologies for off-topicness.]
--
Andy Walker, School of MathSci., Univ. of Nott'm, UK.
a...@maths.nott.ac.uk
> I realise that I didn't describe my example carefully enough. I
> meant to say a declaration of a static INLINE function including
> the keyword "extern" inside an arbitrary expression. The point
> being that the standard requires the properties of such a
> declaration to 'leak' outside the scope which encloses it.
Where is the problem with that? So it would leak.
> Oh, THAT would be easy enough to kludge up. The scope of any
> declaration could be the expression immediately enclosing it,
> unless that expression is a complete statement in which case it
> would be as at present. Simple to define and not all THAT messy.
It's simpler. I've done it for another language. You shouldn't view
a declaration as a kind of an expression or statement. You should view
declaration; expression
as an expression in a whole, with the semicolon being a part of the
declaration syntax, different than semicolon separating expressions.
It's like 'let declaration in expression' in functional languages.
There is no point in asking about the "value of a declatation".
Declaration is not an expression. But there is no problem in using
declarations inside expressions.
There's no problem with declarations being expressions, either, if
your not fixated on single-valued expressions in your language.
(You are then faced just with pragmatic issues about likely errors
and style. For example consider the following interaction with an
incremental compiler, where "-)" is the prompt:
-) (var x = 11) + (1, 2);
3
The *meaning* is perfectly straightforward; but you might want to
object to the *style*. The question becomes, is it worth making
complicated style rules and binding them into the language a priori?)
--
Chris "yes, it's a real example" Dollin
If I may repeat what I said:
... Now think of that
arbitrary expression being inside sizeof or the size of an array
parameter ....
Think of the consequences of a property leaking out from a
construction that is not evaluated and, worse, is eliminated
during translation phase 7.
This is especially hairy in my example as linkage of the sort I
was describing is partially a phase 7 activity, and partially a
phase 8 one.
Actually the idea is already there in C++. For example:
for(iterator i = 0; fstream nextfile(i); ++i) { /* process file */ }
The control expression has to be evaluated as a bool even though it is a
declaration.
> ... Now think of that
> arbitrary expression being inside sizeof or the size of an array
> parameter ....
>
> Think of the consequences of a property leaking out from a
> construction that is not evaluated
I don't see any bad consequences.
> and, worse, is eliminated during translation phase 7.
>
> This is especially hairy in my example as linkage of the sort I was
> describing is partially a phase 7 activity, and partially a phase
> 8 one.
Well, one of the following applies:
1. It's necessary to remove such unevaluated expressions before the
linkage declaration has the effect, otherwise rules would make
no sense.
2. It's necessary to apply the linkage specification effect before
such unevaluated expressions are removed, otherwise rules wihot
make no sense.
3. Both of the above interpretations are possible: there is no
inherent order between these compilation activities.
If case 1 is true, then there is no problem: such declarations are
ignored in these cases.
If case 2 is true, then there is no problem either, such declaration
are effective in these cases too.
If case 3 is true, then the language definition should decide which
is the case. It's not important which is chosen, because these cases
are pathological anyway - there is no reason why a sane programmer
would make such construct.
I don't see a problem.
>> Declaration is not an expression. But there is no problem in using
>> declarations inside expressions.
>
> There's no problem with declarations being expressions, either,
> if your not fixated on single-valued expressions in your language.
Well, there is no problem even when expressions return a single value
when you already have an equivalent of void, nil, None - whatever
procedures executed for their side effects return. This can be the
value of a declaration-as-expression.
> (You are then faced just with pragmatic issues about likely errors
> and style.
Indeed, ending a sequence of declarations without a proper expression
at the end is likely an error.
> For example consider the following interaction with an
> incremental compiler, where "-)" is the prompt:
>
> -) (var x = 11) + (1, 2);
> 3
Guess what? It almost works in my little language, where expressions
do have multiple results. This
(x = 11) + (1, 2)
would return 3, except that I removed the comma syntax this morning,
because it can be easily simulated by the identity function (multiple
arguments, multiple results). Now it would be written
(+) (x = 11) 1 2
and of course there is no reason to write an expression without side
effects and with guaranteed empty result as an argument of a function.
Sorry for that off topic posting. I slipped from comp.std.c++ to
comp.std.c without noticing.
(by the way, your newsposter must be doing something to your posts
that my newsreader interprets as "make this font almost, but not quite,
too tiny to read". Could you switch it off, or could some knews expert
tell me how to switch *mine* off?)
> 27 Sep 2001 10:11:29 GMT, ke...@hplb.hpl.hp.com () <ke...@hplb.hpl.hp.com> pisze:
>
>>> Declaration is not an expression. But there is no problem in using
>>> declarations inside expressions.
>>
>> There's no problem with declarations being expressions, either,
>> if your not fixated on single-valued expressions in your language.
>
> Well, there is no problem even when expressions return a single value
> when you already have an equivalent of void, nil, None - whatever
> procedures executed for their side effects return. This can be the
> value of a declaration-as-expression.
That depends. Suppose `f` is a function of two arguments.
f( 1, var x = 42, 2 );
can get two arguments if declarations return no values, but three if
they return the I'm-not-a-value-really-guv value (void, nil, whatever).
>> (You are then faced just with pragmatic issues about likely errors
>> and style.
>
> Indeed, ending a sequence of declarations without a proper expression
> at the end is likely an error.
I cannot get a good handle on the odds, however. (If the expressions
may have side-effects, for example, it may just be a final declaration
used to eat the final results, for consistency with the style of the
rest of the code - which might be machine-generated.)
>> For example consider the following interaction with an
>> incremental compiler, where "-)" is the prompt:
>>
>> -) (var x = 11) + (1, 2);
>> 3
>
> Guess what? It almost works in my little language, where expressions
> do have multiple results.
It worked as typed in mine. (Looks around nervously.) Er ... I think
we're losing all connection with the standardisation of C. What say
we stop here, and if you want to discuss stuff with me, go to email?
> arguments, multiple results). Now it would be written
> (+) (x = 11) 1 2
> and of course there is no reason to write an expression without side
> effects and with guaranteed empty result as an argument of a function.
A declaration *does* have a side-effect, however, although in this context
there's no reason to write it in that position; but consider
f( var x = horridExpr, x );
[although I'd write that as f(horridExpr ->> var x) in practice, when
I've rearranged the declaration syntax As Per Plan]
--
Chris "electric hedgehog" Dollin
I'd like to bring in the fact, that C is also used by a large amount of
people
having completely different "human language handling means" than native
english
speakers. In fact, "human language handling" is completely variable and
accounting
for this, any assumptions on it should not be used in a language that is
used to describe
things very determinstic.
Example: In dutch the word "UNLESS" translates to "ZONIET" meaning directly
"IF NOT". One
might think that the two statements are completely equivalent to the dutch.
But "ZO"->"IF" translates
by very indirect inference, due to the "ZO" prepended to "NIET",
"NIET"->"NOT" translates very direct.
In fact 0.1% of the times the word "ZO" is used it means "IF" ( and mostly
if prepended to NIET), the other
99.9%, "ZO" more resembles the word "LIKE", Needless to say the word
"ZONIET" is not used often
due to dutch lazyness. The dutch developed a mindset in which UNLESS
constructions are mostly done differently
by making completely different sentences, or stories. Reading "UNLESS"
requires a (splitsecond) more thinking.
>
> I find it fractionally easier to read the second, but (like most
> people) am happy with either. In general, I am less happy with:
>
> UNLESS (NOT (condition)) statement
Needless to say that (after a split second) "IF NOT NOT" seems _very_
redundant to the dutch.
The linguists tell me that actually it isn't; apparently much of
human linguistic structure is directly due to the way our brains
are prewired.
As to what logical constructs are easiest to read, it does vary;
mainly it seems to depend on what one is accustomed to. At one
time I could read genuine Polish notation (ECpqNr) nearly as
well as my native language.
In "Structured Programming With go to Statements" (1974) by
Donald Ervin Knuth:
Ole-Johan Dahl has recently proposed a syntax which I think is
the first real solution to the n + 1/2 problem. He suggests
writing the general simple iteration defined above as
loop: S; while B': T; repeat;
where, as before, S and T denote sequences of one or more
statements reparated by semicolons. Note that as in two of
our original 'go to'-free examples, the syntax refers to
condition B' which represents staying _in_ the iteration,
instead of condition B which represents exiting; and this may
be the secret of its success.
Dahl's syntax may not seem appropriate at first, but actually
it reads well in every example I have tried, and I hope the
reader will reserve judgment until seeing the examples in the
rest of this article. One of the nice properties of his
syntax is that the word 'repeat' occurs natually at the end of
a loop rather than at its beginning, since we read actions of
the program sequentially. As we reach the end, we are
instructed to repeat the loop, instead of being informed that
the _text_ of the loop (not its execution) has ended.
Furthermore the above syntax avoids ALGOL's use of the word
'do' (and aols the more recent unnatural delimiter 'od'); the
word 'do' as used in ALGOL has never sounded quite right to
native speakers of English, it has always been rather quaint
for us to say "do read (A[i])" or "do begin"! Another feature
of Dahl's proposals is that it is easily exiomatized along the
lines proposed by Hoare:
{P} S {Q}
{Q ^ B'} T {P}
------------------------------------------------------
{P} loop: S; while B': T; repeat; {Q ^ ! B'}
(Here I am using braces around the assertions, as in Wirth's
PASCAL language, instead of following Hoare's original
notation "P {S} Q," sincde assertions are, by nature,
parenthetical remarks.)
The nicest thing about Dahl's proposal is that it works also
when S ot T is empty, so that we have a uniform syntax for all
three cases: The 'while' and 'repeat' statements found in
ALGOL-like languages of the late 1960s are no longer needed.
When S or T is empty, it is appropriate to delete the
preceding colon. Thus
loop while B':
T;
repeat;
takes the place of "while B' do begin T end;" and
loop:
S
while B' repeat;
takes the place of "repeat S until B;". At first glance these
may seem strange, but probably less strange than the 'while'
and 'repeat' statements did when we first learned them.
--
@P=split//,".URRUU\c8R";@d=split//,"\nrekcah xinU / lreP rehtona tsuJ";sub p{
@p{"r$p","u$p"}=(P,P);pipe"r$p","u$p";++$p;($q*=2)+=$f=!fork;map{$P=$P[$f^ord
($p{$_})&6];$p{$_}=/ ^$P/ix?$P:close$_}keys%p}p;p;p;p;p;map{$p{$_}=~/^[P.]/&&
close$_}%p;wait until$?;map{/^r/&&<$_>}%p;$_=$d[$q];sleep rand(2)if/\S/;print