sommar@enea.se (Erland Sommarskog) (08/15/89)
There is currently a discussion going on in comp.lang.misc under the subject "What I like to see in an if-statement", and the subject line I have chosen shows the desired feature. In short the rule for a relational expression should be something like: Rel_exp ::= Expression (Rel_op Expression)* where ()* means one or more occurences. The semantic interpretation would be than of a logical AND so that: a < b <= c > a + 2 would be a shorthand for a < b AND b <= c AND c > a + 2 When I took a compiler course ages ago, the little language I defined had this feature. And there are several occasions when this would relational expressions shorter and thus easier to read since what is omitted is superflouos syntactic noise. I mentioned this in an article, and one reponse agreed with me, and answered my question why so few language had it with the simple "Algol didn't have it". And it sounds likely. When you sit down and design a new language, things like boolean expressions is just something you "take off the shelf". Anyway, since Eiffel still is open for the changes for some more time, why not take the chance and add it? Not an essential thing, but one of those little things that makes life easier. Or is there some problem I have over-looked? -- Erland Sommarskog - ENEA Data, Stockholm - sommar@enea.se "Hey poor, you don't have to be Jesus!" - Front 242
bertrand@eiffel.UUCP (Bertrand Meyer) (08/28/89)
From article <182@enea.se>, sommar@enea.se (Erland Sommarskog): > [...] The rule for a relational expression should be something like: > Rel_exp ::= Expression (Rel_op Expression)* > [...] The semantic interpretation would be than of a logical AND so that: > a < b <= c > a + 2 > would be a shorthand for > a < b AND b <= c AND c > a + 2 > [...] Since Eiffel still is open for changes for some more time, > why not take the chance and add it? Not an essential thing, > but one of those little things that makes life easier. Or > is there some problem I have overlooked? I have tried to find an argument for not following Mr. Sommarskog's suggestion and I cannot think of one. As a matter of fact, many assertions in the basic Data Structure Library and elsewhere would be written more simply in this way. It may be that the reason why no mainstream language has included the form suggested by Mr. Sommarskog is that people feared ambiguity. But the simple semantics he suggests (``and'') makes any such fear unfounded. At first (and second) sight this seems to be the kind of extension that only has advantages. It should find its way into version 3. -- Bertrand Meyer bertrand@eiffel.com
sommar@enea.se (Erland Sommarskog) (08/30/89)
Bertrand Meyer (bertrand@eiffel.UUCP) writes: > It may be that the reason why no mainstream language has included the >form suggested by Mr. Sommarskog is that people feared ambiguity. As I said in my first article it's more likely intertia as correspondent said to me in mail. > At first (and second) sight this seems to be the kind of extension >that only has advantages. It should find its way into version 3. I'm pleased to hear to contributed to Eiffel's development. There is one more detail to think of though: a < b < f() Should the language guarantee that f is called? Or should the compiler be allowed to skip the call if a >= b? My view is the latter, and a quick glance in OOSC doesn't say that Eiffel has a differnt philosophy. As the Ada LRM would say: a program that relies on a expression being computed in any particular order is erroneous. -- Erland Sommarskog - ENEA Data, Stockholm - sommar@enea.se The law of gravity should be forbidden execpt in downhills.
marku@cheops.eecs.unsw.oz (Mark Utting) (08/31/89)
From article <192@eiffel.UUCP>, by bertrand@eiffel.UUCP (Bertrand Meyer): > From article <182@enea.se>, sommar@enea.se (Erland Sommarskog): > >> [...] The rule for a relational expression should be something like: >> Rel_exp ::= Expression (Rel_op Expression)* >> [...] The semantic interpretation would be than of a logical AND so that: >> a < b <= c > a + 2 >> would be a shorthand for >> a < b AND b <= c AND c > a + 2 > ........ > > At first (and second) sight this seems to be the kind of extension > that only has advantages. It should find its way into version 3. > > -- Bertrand Meyer I like this abbreviated notation, with one slight reservation. "a < b <= c" is fine, but "d < e > f" seems to me to be less readable than using an explicit `and'. I agree that it is not ambiguous given the above semantics, but it makes me wonder what the relationship between "d" and "f" is. When the relational operators all go in the same direction (possibly mixed with equalities), the transitive relationships all hold as well. Eg. "a" is clearly less than "c" in the above. However, when increasing and decreasing operators are mixed, this nice transitive property disappears. I guess I would like to be able to abbreviate sequences of {<,<=,=} operators, and sequences of {>,>=,=} operators, but not mix the two. The specification language Z allows any boolean relational operators to be abbreviated in this way, but published specifications seem to keep to the convention mentioned above. Mark Utting, Dept.Comp.Sci, UNSW, PO Box 1, Kensington, NSW, Australia 2033 // ACSnet,CSNET: marku@cheops.unsw.oz // BITNET/ARPA: marku%cheops.unsw.oz@uunet.uu.net \// UUCP: ...!uunet!munnari!cheops.unsw.oz!marku
db@lfcs.ed.ac.uk (Dave Berry) (08/31/89)
In article <239@enea.se> sommar@enea.se (Erland Sommarskog) writes: >I'm pleased to hear to contributed to Eiffel's development. There >is one more detail to think of though: > > a < b < f() > >Should the language guarantee that f is called? Or should the compiler >be allowed to skip the call if a >= b? Should the arguments be evaluated left-to-right, right-to-left, or in arbitrary order? Should the argument be evaluated exactly once, at most once, or any number of times? If the value of the expression is known before all the arguments are evaluated, must the remaining arguments be evaluated, must they not be evaluated, or is it up to the compiler? The only strong feeling I have about these issues is that an argument should not be evaluated more than once. I.e. a < f() < b should not be equivalent to a < f() and f() < b but to tmp1 := a -- if evaluation is left-to-right tmp2 := f() tmp1 < tmp2 and tmp2 < b Dave Berry, Laboratory for Foundations db%lfcs.ed.ac.uk@nsfnet-relay.ac.uk of Computer Science, Edinburgh Uni. <Atlantic Ocean>!mcvax!ukc!lfcs!db "Another hope, another dream, another truth, installed by the machine."
afscian@violet.waterloo.edu (Anthony Scian) (08/31/89)
In article <239@enea.se> sommar@enea.se (Erland Sommarskog) writes: >I'm pleased to hear to contributed to Eiffel's development. There >is one more detail to think of though: > > a < b < f() > >Should the language guarantee that f is called? Or should the compiler >be allowed to skip the call if a >= b? My view is the latter, and a >quick glance in OOSC doesn't say that Eiffel has a differnt philosophy. The expression a < b < c could expand into: a < b AND IF b < c rather than a < b AND b < c for boolean expressions in code and for assertions: a < b ; b < c This would be the most useful expansions for the construct. Anthony //// Anthony Scian afscian@violet.uwaterloo.ca afscian@violet.waterloo.edu //// "I can't believe the news today, I can't close my eyes and make it go away" -U2
ankle@ics.uci.edu (Rod Shankle) (09/01/89)
> should a < b < f () be allowed and if a >= b should the function be > called or not ?? Well, since f () is a function and functions shouldn't have any side effects (refer to OOSC for a lot of examples and reasons why they shouldn't) it doesn't matter (unless your profiling the program) if f () gets called or not. With that restriction even an expression such as a < f () < c should be allowed. BTW, most compilers evaluate IF a < b AND b < c THEN as IF a >= b THEN FALSE ELSE b < c --- SHML ---
bbadger@x102c.harris-atd.com (Badger BA 64810) (09/03/89)
In article <1300@cheops.eecs.unsw.oz> marku@cheops.eecs.unsw.oz (Mark Utting) writes: [...] > >I like this abbreviated notation, with one slight reservation. > >"a < b <= c" is fine, but "d < e > f" seems to me to be less readable >than using an explicit `and'. I agree that it is not ambiguous given >the above semantics, but it makes me wonder what the relationship between >"d" and "f" is. > >When the relational operators all go in the same direction (possibly mixed >with equalities), the transitive relationships all hold as well. ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ >Eg. "a" is clearly less than "c" in the above. >However, when increasing and decreasing operators are mixed, this nice >transitive property disappears. > >I guess I would like to be able to abbreviate sequences of {<,<=,=} >operators, and sequences of {>,>=,=} operators, but not mix the two. > >The specification language Z allows any boolean relational operators >to be abbreviated in this way, but published specifications seem to >keep to the convention mentioned above. > Please excuse my ignorance of Eiffel syntax. I don't know the syntax of Eiffel, but I've been following this discussion with interest. (Perhaps someone could post an abbreviated Eiffel syntax, to give us some of the flavor?) Also, in what follows, I'm assuming that relational operators can be defined on user-defined data types. If this isn't so, I'm sorry. Holding to a single ``flow'' might seem to avoid ``syntax shock'', but not all boolean operations on objects yeild transitive relations. That is,``a < b and b < c'' does not imply ``a < c''. My favorite example of this is a probability function which compares the outcome of dice. I'll use C syntax (sorry): Given: typedef int die_t [6]; die_t a = {3,3, 3,3, 3,3}; die_t b = {2,2, 2,2, 6,6}; die_t c = {1,1, 4,4, 4,4}; int win_loss ( die_t p, die_t q) { int i,j; int win_loss; count = 0; for (i = 0; i < 6; i++) { for (j = 0; j < 6; j++) { if ( p[i] > q[j] ) count ++; if ( p[i] < q[j] ) count --; }} } int wins ( die_t p, die_t q) { return win_loss(p,q) > 0;} int loses ( die_t p, die_t q) { return win_loss(p,q) < 0;} Now it turns out that: win_loss loses Relation (`a<b' is `loses(a,b)') -- ----- a b 12 True a < b b c 4 True b < c a c -12 FALSE! not ( c < a ) Also keep in mind that ``not (a<=b)'' does not necessarily imply ``a>b''. Even when (a<b) <==> (b>a) . For example, (not subset(a,b) and not eq(a,b)) does not imply (subset(b,a)). In conclusion, I like the idea of a compact notation, but I think you'll have to restrict the relational operators. In Ada, for example, the not-equals operator (``/='') is derived from the equals operator and the pre-defined BOOLEAN ``not'' operation. You cannot define ``/='' independently of ``=''. On the other hand, in Ada, ``<='' is totally independent of ``<'' and ``=''. The relational operators are, I think, constrained to return a BOOLEAN type. (It's been a while, so I might be wrong on this.) What constraints to relational operators should be applied? What about purity and simplicity? Does common usage supersede simplicity? ----- - - - - - - - ---- Bernard A. Badger Jr. 407/984-6385 |``Get a LIFE!'' -- J.H. Conway Harris GISD, Melbourne, FL 32902 |Buddy, can you paradigm? Internet: bbadger%x102c@trantor.harris-atd.com|'s/./&&/g' Tom sed expansively.
diamond@csl.sony.co.jp (Norman Diamond) (09/04/89)
In article <1300@cheops.eecs.unsw.oz> marku@cheops.eecs.unsw.oz (Mark Utting) writes: >I like this abbreviated notation, with one slight reservation. >"a < b <= c" is fine, but "d < e > f" seems to me to be less readable >than using an explicit `and'. I agree that it is not ambiguous given >the above semantics, but it makes me wonder what the relationship between >"d" and "f" is. If you find "d < e > f" confusing, then vote against it at your employer's style meeting. Or forbid your subordinates to do it. >The specification language Z allows any boolean relational operators >to be abbreviated in this way, but published specifications seem to >keep to the convention mentioned above. This seems rather suitable. Keep the rules simple so they can be understood. Bad programmers will be able to write bad programs, but not everyone will have to. -- -- Norman Diamond, Sony Corporation (diamond@ws.sony.junet) The above opinions are inherited by your machine's init process (pid 1), after being disowned and orphaned. However, if you see this at Waterloo or Anterior, then their administrators must have approved of these opinions.
potter@ultima.cs.uts.oz (John Potter) (11/25/89)
From article <192@eiffel.UUCP>, by bertrand@eiffel.UUCP (Bertrand Meyer): >From article <182@enea.se>, sommar@enea.se (Erland Sommarskog): > > > [...] The rule for a relational expression should be something like: > > Rel_exp ::= Expression (Rel_op Expression)* > > [...] The semantic interpretation would be than of a logical AND so > that: > > a < b <= c > a + 2 > > would be a shorthand for > > a < b AND b <= c AND c > a + 2 > > [...] Since Eiffel still is open for changes for some more time, > > why not take the chance and add it? Not an essential thing, > > but one of those little things that makes life easier. Or > > is there some problem I have overlooked? > > I have tried to find an argument for not following > Mr. Sommarskog's suggestion and I cannot think of one. > As a matter of fact, many assertions in the basic Data Structure > Library and elsewhere would be written more simply in this way. > > It may be that the reason why no mainstream language has > included the form suggested by Mr. Sommarskog is that people feared > ambiguity. > But the simple semantics he suggests (``and'') makes any such fear > unfounded. I've just got around to reading these articles and their followups. It may be of passing interest to note that the language Miranda allows precisely this form of relational expression. Miranda is a functional language with non-strict semantics (i.e. uses lazy evaluation). The semantic interpretation of a < b <= c > a + 2 would be akin to the Eiffel form a < b and then b <= c and then c > a + 2 The "then" corresponds to the non-strict semantics in Miranda. I don't wish to debate whether Miranda is a mainstream language or not, but it is attracting considerable interest as a vehicle for introductory programming courses (more or less in competition with Scheme). In our first year courses in Computer Science here at the University of Technology, Sydney, we are currently introducing our students to both Miranda and Eiffel. Miranda is taught as part of a Discrete Mathematics subject, and Eiffel within our programming subjects.
yost@esquire.UUCP (David A. Yost) (11/27/89)
In article <16655@ultima.cs.uts.oz> potter@ultima.cs.uts.oz (John Potter) writes: > > From article <192@eiffel.UUCP>, by bertrand@eiffel.UUCP (Bertrand > Meyer): > >From article <182@enea.se>, sommar@enea.se (Erland Sommarskog): >> >> > [...] The rule for a relational expression should be something like: >> > Rel_exp ::= Expression (Rel_op Expression)* >> > [...] The semantic interpretation would be than of a logical AND so >> that: >> > a < b <= c > a + 2 >> > would be a shorthand for >> > a < b AND b <= c AND c > a + 2 >> > [...] Since Eiffel still is open for changes for some more time, >> > why not take the chance and add it? Not an essential thing, >> > but one of those little things that makes life easier. Or >> > is there some problem I have overlooked? >> >> I have tried to find an argument for not following >> Mr. Sommarskog's suggestion and I cannot think of one. >> As a matter of fact, many assertions in the basic Data Structure >> Library and elsewhere would be written more simply in this way. >> >> It may be that the reason why no mainstream language has >> included the form suggested by Mr. Sommarskog is that people feared >> ambiguity. >> But the simple semantics he suggests (``and'') makes any such fear >> unfounded. > >I've just got around to reading these articles and their followups. > >It may be of passing interest to note that the language Miranda allows >precisely this form of relational expression. Miranda is a functional >language with non-strict semantics (i.e. uses lazy evaluation). >The semantic interpretation of > a < b <= c > a + 2 >would be akin to the Eiffel form > a < b and then b <= c and then c > a + 2 >The "then" corresponds to the non-strict semantics in Miranda. OK, I guess it's time someone said that the Icon programming language (available free from icon-project@arizona.edu, but please give them a few bucks) can do this, plus Icon expressions yield more information. In most languages you could divide the world of expression values into two types: boolean (used for control structures) and non- boolean. In Icon, by contrast, every expression acts as both. Every expression either "succeeds" or "fails", giving you your true/false indication, if you want to use it, and, if the expression succeeds, it has a (non-boolean) value, if you want to use it. When any subexpression fails, expression evaluation stops, and the entire expression fails. And everything is an expression in Icon; there are no statements. If a relational expression succeeds, it takes the value of the right side. So, the expression (a < b) + 1 < c evaluates like this a b c expression --- --- --- ----------------- 2 1 3 no value - fails because a < b fails 1 2 3 no value - fails because b + 1 < c fails 1 2 4 c This succeed/fail property of Icon expressions is nice to use in practice. Yet there is more still: if an expression succeeds, it can be resumed, at which point it can yield another value or fail. Thus, you will see many forms of multi-valued "generator" expressions. You can use each value in turn or just the first value, if you like. For instance, the expression 1 to 3 which yields 1, then 2, then 3, ... then fails. There are various control structures that make it easy to take advantage of the multiple values that expressions can generate, such as every expression [ do expression ] while expression [ do expression ] For example, every x := 1 to 3 do write (x) Of course, Icon subroutines either succeed or fail, and can be written to generate additional values when resumed. Icon is neat. My ideal language would be an Icon-ish Eiffel, that is, for example, everything a succeed/fail multi-valued expression instead of some things statements and some things expressions, {} syntax instead of keywords, semicolons optional, and icon-like lists in the library. --dave yost
budd@mist.cs.orst.edu (Tim Budd) (11/28/89)
I'm developing a new programming language called LEDA, which is designed to be ``multiparadigm''. That is, you can program in a logical (prolog style), functional, object oriented or imparative style - or in any mix. It provides generators similar (and largely taken from) Icon, as well as many other features. Several papers on LEDA are in various pipelines, but none has seen daylight yet. If you want to see various technical reports let me know and I can send them. --tim budd (budd@cs.orst.edu)
peter@ficc.uu.net (Peter da Silva) (11/29/89)
I would like to note that this syntax has been used before. I implemented a real-time control language that did this about 6 or 7 years ago. It's very easy to implement, and the ambiguity does not produce much difficulty in practice. I was skeptical at first, but now I'm a convert. Too bad that project ended up getting canned due to overengineering. :-< -- `-_-' Peter da Silva <peter@ficc.uu.net> <peter@sugar.lonestar.org>. 'U` -------------- +1 713 274 5180. "The basic notion underlying USENET is the flame." -- Chuq Von Rospach, chuq@Apple.COM