I wrote:
> > Semantically, CASE is no different from IF.
and Roger Glover wrote:
> If you believe this, you have not thought out the implications
> completely [1]. Even if we were to allow REAL case expressions,
> SELECT CASE would still express a limited subset of the semantics
> of a block IF.
Of course, Roger is right. I should have said that, in principle,
there's nothing you can do with CASE that you can't do with IF. That
is, one can _always_ translate CASE to IF without losing any semantic
contant. I should furthermore have been more specific that the goal is
to reduce irregularity and extend functionality of CASE, in the direction
of IF, without going so far as to lose the useful distinctions from IF:
1. Evaluate the case selector expression once, and
2. Express the intent that ranges are disjoint.
(Otherwise, why keep both of them?)
> > The existence of an
> > efficient implementation for an important subset of the usages of a
> > construct should not be used as an argument against the utility of the
> > other usages -- it looks more like an excuse than a reason.
>
> Actually, it is a "motivation." That is, it is a goal or purpose
> useful to keep in mind while working with or thinking about the
> construct.
Bafflegab. I can implement X by method Y. Therefore I can't implement X'?
Nonsense.
> > Would you expect / hope for use of indexing if you wrote:
> > SELECT CASE(J) ; CASE(1) ; ... ; CASE(1000000) ; ... END CASE
> > if there were no other cases? Wouldn't hashing be too much clanking
> > machinery? I would expect and hope for an IF-tree under-the-covers.
> I suppose it would depend on what was inside the "..."s and how
> much memory bandwidth is available for instructions. On a Cray
> vector machine with one simple assignment under each case, there is
> no doubt you are right; in most codes jump times are a non-issue.
> On a PC or RISC system with long cache lines and with heaps of code
> under either of the "..."s, I would hope for partial second-order
> hashing at least [2].
I had in mind that ... was the stuff _between_ CASE statements, and
didn't contain any, so a jump table would have 1000000 elements, of
which 2 contain something meaningful. I suspect your compiler turns
this case into IF (J == 1) THEN ... ELSE IF (J == 1000000) THEN ..., not
GOTO (10, 30, 30, 30, ............, 30, 30, 20), J ! 999998 30's between
10 ... ; goto 40 ! do J == 1 stuff
20 ... ; goto 40 ! do J == 1000000 stuff
30 STOP 'ERROR'
40 CONTINUE ! END CASE
> > If REAL ranges of CASE were allowed, there would be nothing to prevent
> > the compiler to do what Glover likes (when it's appropriate).
>
> Well then, why not drop some of the other artificial limitations
> that separate SELECT CASE semantics from block IF semantics? Why
> not allow COMPLEX case expressions? Derived type case expressions?
> Array-valued case expressions? Pointer-valued case expressions?
> Why not let the "case values" be any expression, and not just an
> initialization expression (as it is now)? Why not allow "case
> ranges" to overlap? Why not allow multiple comma-separated lists
> of case expressions with corresponding multiple comma-separated
> lists of case selectors on each CASE statement?
Are you really serious, or just trying to reduce the strength of my
arguments by introducing silly spurious alternatives? I'll pretend
you're serious.
1. <= isn't defined for COMPLEX, so allowing COMPLEX _introduces_ an
irregularity, it doesn't _remove_ one. That is, only point ranges
would be allowed.
2. Allow derived type case expressions only if <, <= and == are all
defined for the type (and accessible). Same reason as above.
3. R803: ... IF ( scalar-logical-expr ) THEN
Allowing array-valued case selector expressions _introduces_ an
irregularity, it doesn't _remove_ one.
4. None of <, <=, == are defined on the pointers themselves. Only on
the things they point at (sometimes). I'm not sure what "drop ...
limitations ... Pointer-valued case expressions?" means. I can
certainly write SELECT CASE (J) ... even if J has the POINTER attribute.
5. Allowing CASE values to be non-initialization expressions, and
allowing CASE ranges to overlap remove the useful distinctions
between IF and CASE (but I _did_ propose one useful extension that
adds a non-initialization part to a CASE range declaration in 97-114).
6. Multiple comma-separated lists of ... would be useful in a fully
parallel environment.
> Where does it end?
Just before it gets silly, or inconsistent, or introduces inevitable
expense for other usage usages (which REAL doesn't).
> > One recently raised objection is that a program might have different
> > meaning on different platforms, or might compile on some, but not on
> > others, because different precisions and rounding methods might cause
> > REAL ranges to have different boundaries, or to overlap. This is _no_
> > different from the situation with IF, except that with IF you don't get
> > any help from the compiler in the case when ranges overlap.
>
> The "no overlap" rule is also an artificial restriction of SELECT
> CASE relative to block IF. The difference appears to be that you
> have a use for the "no overlap" restriction, but you do not have a
> use for the "discrete types only" restriction.
Exactly.
> The problem with REALs in your scenario is that "range overlap"
> detectable at compile time could be different than "range overlap"
> detectable at runtime! Any rule to the contrary would implicitly
> prohibit (or at least grossly complicate) cross-platform compiling.
> This reasoning is a straight-forward corollary to the reasoning for
> the restriction against floating point operations in initialization
> expressions.
I don't have _any_ syntax to express the desire that I want disjoint
ranges in the case of REAL selectors.
I don't know of any cross-platform compilers, or any that anybody plans
to do. This is really down in the noise. Even in a cross-compiling
environment, this is down in the noise, as compared to other problems,
and at least this one is solvable. Even counting the expense to solve
it, it's _still_ down in the noise.
> > If the compilers work correctly, one should be able to prevent overlap
> > and non-portable behavior by writing
> > CASE (A <= * <= B) ; ... ; CASE (B < * <= C) ; ...
> > or CASE (A <= * <= B) ; ... ; CASE (B+NEAREST(B,1.0) <= * <= C); ...
> ^^^^^^^^^^^^^^^^
> In the first place, in think you mean simply "NEAREST(B,1.0)".
Certainly. My blunder. I'd use the first alternative, anyway.
> In the second place, this would require the standard to accept a
> case value that is not an initialization expression (it contains a
> REAL-valued intrinsic); where does it end?
This was accepted at meeting 143 (paper 97-250r2), so it apparently
ends beyond what Roger thinks is silly.
> In the third place, there are many other ways "range overlap"
> might happen. For example:
> CASE ( 3.14159265358979 ); ...
> CASE ( 3.14159265358980 ); ...
> The compiling environment might see these as the same REAL value
> when the runtime environment would not have, or vice versa.
This is a quality of implementation issue that may affect sale-ability
of the development system. The programer deserves what he gets. As
Artur Swietanowski wrote, using Fortran requires some numeric literacy.
> > (I prefer the first), except in the case when the ranges degenerate to
> > emptyness (and then the compiler should produce a message).
> >
> > (This is, by the way, related to the reason to prohibit REAL loop
> > inductors: the number of "trips" might vary from platform to platform.)
>
> As is the argument *against* allowing REAL-valued case expressions.
One doesn't have the accumulation-of-roundoff problem in REAL-valued
case selectors that one has in REAL-valued DO inductors. The CASE
values are static. The problems are only tenuously related.
> > Other objections are described in paper 97-114. So far, I consider all
> > objections to allowing REAL range for CASE to be "excuses," not
> > "reasons."
>
> By this reasoning, any argument in favor of any other restricted
> syntax that results in SELECT CASE having less functionality than
> that of a block IF is also an "excuse."
No, only the silly ones. And I still want to preserve the useful
distinctions spelled out at the top.
Best regards,
Van
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|