tneff@bfmny0.UUCP (Tom Neff) (08/09/89)
The obvious drawback to defining 'triadc' as a macro #define triadc(a,o1,b,o2,c) ((a o1 b) && (b o2 c)) is side effects, e.g. if (triadc(' ', *cp++, '_')) do_the(wrong, thing); /* :-) */ -- "We walked on the moon -- (( Tom Neff you be polite" )) tneff@bfmny0.UU.NET
karl@haddock.ima.isc.com (Karl Heuer) (08/10/89)
In article <8577@batcomputer.tn.cornell.edu> lacey@tcgould.tn.cornell.edu (John Lacey) writes: >As I think we have all agreed that C is not the place for these extended >constructs, I have directed follow-ups to comp.lang.misc. I agree; sorry I didn't redirect it myself. (c.l.m readers: the topic is the hypothetical change to C to make "x < y < z" mean what a mathematician would expect, rather than the useless interpretation that C currently attaches to it, viz. "x<y && 1<z || x>=y && 0<z".) >I agree that it doesn't belong in C. However, I also happen to think that >Icon's semantics are horrible. The idea that (a < b) either fails to produce >a result or evaluates to b is completely unintuitive. Well, the only time you care that it happens to evaluate to b is when you're writing "a < b < c"; otherwise, you just use it in a boolean context, where the only important part is whether it's true or false (i.e. does or doesn't return a value). The actual value doesn't matter. I don't see that this is any more of a problem than the fact that most implementations of isalpha() return a random nonzero value (not necessarily 1) for success. >[karl@haddock.ima.isc.com (Karl Heuer) writes:] >>I doubt that the parse is any more difficult than the dangling-else problem. > >The parse would be more difficult. The problems aren't analogous. The >dangling-else problem is one of ambiguity. Parsing a general relational >expression is difficult because the same string will be used for multiple >tokens. For example, in (a < x < b), x has to be associated separately >to its left and right. I don't see what you're getting at. You simply add a new production rule which parses "a < x < b" as a ternary operator, and produce code equivalent to evaluate x into temp compare a with temp jump-if-ge FALSE-BRANCH compare temp with b jump-if-ge FALSE-BRANCH Generating the temporary is trivial for a compiler; it's not as if this had to be parsed by a macro preprocessor. The lookahead to distinguish the constructs "E < E < E" and "E < E" is, I believe, no worse than the problem of distinguishing "if (E) S;" and "if (E) S; else S;". Karl W. Z. Heuer (ima!haddock!karl or karl@haddock.isc.com), The Walking Lint
preston@titan.rice.edu (Preston Briggs) (08/11/89)
In article <14251@haddock.ima.isc.com> > karl@haddock.ima.isc.com (Karl Heuer) writes: > ... You simply add a new production rule >which parses "a < x < b" as a ternary operator, >and produce code equivalent to > evaluate x into temp > compare a with temp > jump-if-ge FALSE-BRANCH > compare temp with b > jump-if-ge FALSE-BRANCH >Generating the temporary is trivial for a compiler; >it's not as if this had to >be parsed by a macro preprocessor. > >The lookahead to distinguish the constructs "E < E < E" and "E < E" is, I >believe, no worse than the problem of distinguishing "if (E) S;" and >"if (E) S; else S;". But you wouldn't want a single production to get a<b<c as a ternary operator; you really want to be able to handle a < b < c < ... < n And do you want it restricted to conditionals, or extended to all expressions/statements? This should all be easy; but I don't like it. It feels "unnatural." I think the problem is that you want to make relational operators into a sort of control flow thing -- not really operators at all. Compare + with your version of <. a+b+c means (a + b) + c but a<b<c doesn't mean (a < b) < c or a < (b < c) So, I guess it's a doable idea; it's just going to feel really unnatural to a lot of people. I prefer Pascal's version, where it is illegal to write a<b<c at all. This avoids any misinterpretation. On the other hand, I'd prefer a few more levels of precedence allowing me to write a<b and b<c instead of (a<b) and (b<c) On the other hand, versions of LISP allow things like (+ a b c d) and (< a b c d) which seems best of all. Maybe we should just give up on "normal" algebraic notation as a bad idea extended too far. Regards, Preston Briggs preston@titan.rice.edu
lacey@batcomputer.tn.cornell.edu (John Lacey) (08/11/89)
In article <516@brazos.Rice.edu> (3383 of comp.lang.misc) preston@titan.rice.edu (Preston Briggs) writes: } } And do you want it restricted to conditionals, or extended } to all expressions/statements? It would be a relational expression, of course, just like "a < b". } This should all be easy; but I don't like it. It feels "unnatural." } I think the problem is that you want to make relational operators } into a sort of control flow thing -- not really operators at all. } Compare + with your version of <. } } a+b+c means (a + b) + c } but } a<b<c doesn't mean (a < b) < c } or a < (b < c) Just because the expression doesn't commute or associate doesn't mean it is not a valid relation. It certainly is not "a sort of control flow thing". } So, I guess it's a doable idea; it's just going to feel } really unnatural to a lot of people. I prefer Pascal's } version, where it is illegal to write a<b<c at all. } This avoids any misinterpretation. So far so good (not that I agree with you, but it is your preference). } On the other hand, versions of LISP allow things like } (+ a b c d) } and } (< a b c d) } } which seems best of all. Maybe we should just give up on } "normal" algebraic notation as a bad idea extended too far. One is postfix and the other is infix, but they have identical meanings. So why is one unnatural and the other best of all? Also, perhaps there are places where algebraic notation [which, by the way, (< a b c d) is an example of] is not the best option, but I don't think that programming languages are such a place. Indeed, algebra is only recently becoming the powerful tool in programming that it is in mathematics (abstract data types, algebraic specification, and so on). } Preston Briggs } preston@titan.rice.edu -- John Lacey lacey@tcgould.tn.cornell.edu cornell!batcomputer!lacey After August 16: jjlacey@owucomcn.bitnet If you have to, try mdl@sppy00.UUCP or maybe {...}!osu-cis!sppy00!mdl
preston@titan.rice.edu (Preston Briggs) (08/11/89)
In article <8606@batcomputer.tn.cornell.edu> lacey@tcgould.tn.cornell.edu (John Lacey) writes: >In article <516@brazos.Rice.edu> (3383 of comp.lang.misc) > preston@titan.rice.edu (Preston Briggs) writes: >} On the other hand, versions of LISP allow things like >} (+ a b c d) >} and >} (< a b c d) >} >} which seems best of all. Maybe we should just give up on >} "normal" algebraic notation as a bad idea extended too far. > >One is postfix and the other is infix, but they have identical meanings. >So why is one unnatural and the other best of all? Also, perhaps there >are places where algebraic notation [which, by the way, (< a b c d) is >an example of] is not the best option, but I don't think that programming >languages are such a place. Indeed, algebra is only recently becoming >the powerful tool in programming that it is in mathematics (abstract data >types, algebraic specification, and so on). Yes, you're certainly correct about my mistakes. On the other hand, the point I was attempting to make still seems valid. That is, explicitely parenthesized prefix notation seems a better representation for complex expressions. I will agree that simple expressions are more simply written in C or Pascal---infix notation and commonly understood rules of precedence help achieve a clear, compact representation. But C has 16 levels of precedence! I think this is an indication of too much complexity crammed into the notion of <expression>. I think Lisp/Scheme/... have the right idea, at least regarding expressions---a simple, consistant notation that can be easily extended. Preston Briggs preston@titan.rice.edu
preston@titan.rice.edu (Preston Briggs) (08/11/89)
In article <8606@batcomputer.tn.cornell.edu> lacey@tcgould.tn.cornell.edu (John Lacey) writes: >In article <516@brazos.Rice.edu> (3383 of comp.lang.misc) > preston@titan.rice.edu (Preston Briggs) writes: >} but >} a<b<c doesn't mean (a < b) < c >} or a < (b < c) > >Just because the expression doesn't commute or associate doesn't mean >it is not a valid relation. But if < doesn't associate, then it doesn't make sense to write a<b<c. In C, < is left-associative. You can write a<b<c (but the meaning is perhaps suprising). In Pascal, < doesn't associate. You can't write a<b<c. Preston Briggs preston@titan.rice.edu
sommar@enea.se (Erland Sommarskog) (08/12/89)
I think John Lacey (lacey@tcgould.tn.cornell.edu) said this: >The parse would be more difficult. The problems aren't analogous. The >dangling-else problem is one of ambiguity. Parsing a general relational >expression is difficult because the same string will be used for multiple >tokens. For example, in (a < x < b), x has to be associated separately >to its left and right. I have to object here. Way back at the university I took a compiler course. In the tiny language I made for my assignment I defined the grammar relational expression something like: rel_exp ::= exp (rel_op exp)* ()* meaning 1 or more times easy. Trivial, isn't it? The semantic interpretation was AND. I.e. 0 < x < 10 was interpreted as (0 < x) AND (x < 10), which seems as the natural interpretation for the case you would like to use it for. A thing like a = b <= z > y < b wouldn't something to recommend but the langauge dealt with it the same way. Actually I have always been surprised that no language I have dealt have had this feature since it is so easy to implement. Am I overlook- ing something? -- Erland Sommarskog - ENEA Data, Stockholm - sommar@enea.se "Hey poor, you don't have to be Jesus!" - Front 242
rrt@halley.UUCP (Robert Teisberg) (08/12/89)
In article <545@brazos.Rice.edu> preston@titan.rice.edu (Preston Briggs) writes: >In Pascal, < doesn't associate. You can't write a<b<c. True, you usually can't, but associativity (or lack thereof) is not the reason. In Pascal, the expression parses as: (a<b)<c where (a<b) is an expression with a boolean value. If c is also boolean, this is a legitimate (though weird) expression. If c is not boolean, the compiler should complain of a type clash. >Preston Briggs >preston@titan.rice.edu -- Bob Teisberg @ Tandem Computers, Inc. | ...!rutgers!cs.utexas.edu!halley!rrt 14231 Tandem Blvd. | soon to be rrt@mpd.tandem.com Austin, Texas 78728 | (512) 244-8119 Any resemblance to the opinions of a real person or corporation is concidental.
preston@titan.rice.edu (Preston Briggs) (08/12/89)
In article <561@halley.UUCP> rrt@halley.UUCP (Robert Teisberg) writes: >In article <545@brazos.Rice.edu> preston@titan.rice.edu (Preston Briggs) writes: >>In Pascal, < doesn't associate. You can't write a<b<c. > >True, you usually can't, but associativity (or lack thereof) is not the >reason. In Pascal, the expression parses as: > >(a<b)<c > >where (a<b) is an expression with a boolean value. If c is also >boolean, this is a legitimate (though weird) expression. If c is not >boolean, the compiler should complain of a type clash. Wait. Check the BNF or railroad tracks. (Pause while I try to find a reference!) In "Algorithms+Data Structures" (all I can find right away), an Expression is defined: Expression ::= SimpleExpression [relation SimpleExpression] where [x] denotes an optional "x". So, an expression is a SimpleExpression, optional followed by a Relation and another SimpleExpression. There can't be more than one relation. Contrast this with the definition of SimpleExpression: SimpleExpression ::= [`+'|`-'] Term {AddOp Term} where {x} denotes 0 or more x's. Here we see an optional leading + or -, followed by a Term, followed by a sequence of AddOp's and Term's. It's possible that some standard has changed this definition in the past few years; I haven't kept up. Try it on your favorite compiler! Preston
karl@haddock.ima.isc.com (Karl Heuer) (08/14/89)
In article <516@brazos.Rice.edu> preston@titan.rice.edu (Preston Briggs) writes: >In article <14251@haddock.ima.isc.com> karl@haddock (Karl Heuer) writes: >>which parses "a < x < b" as a ternary operator, > >But you wouldn't want a single production to get a<b<c as a ternary operator; >you really want to be able to handle a < b < c < ... < n True; I was oversimplifying. I'll cover the general case below. >On the other hand, versions of LISP allow things like > (< a b c d) That doesn't completely solve the problem; I want to be able to write 0 <= i < N without having to throw in +1/-1 on half of the expressions. (I consider a half-open interval to be the more natural endpoint-representation of a range.) Okay, then, here's one way to parse such constructs. A comparison operator like "a < b" returns an object of an internal type "cascadable boolean", whose value is either {FALSE} or {TRUE, b}. If a cascadable boolean is used in any context other than the left operand of a compare, it immediately decays into a normal boolean. If it is the left operand of a compare, then "{FALSE} < c" returns {FALSE} (but should probably still evaluate c for side effects), while "{TRUE, b} < c" returns the same object as "b < c" (another cascadable boolean). This would apply to "==" and "!=" as well as "<" "<=" ">" ">=", and I would make all six operators have the same precedence. (The only reason for having separate precedences for equality and relational operators is to allow a < b == c < d /* do the two relations have the same truth-value? */ , which would still be legal if properly parenthesized -- enclosing a cascadable boolean in parenthesis would also force the decay into a normal boolean.) (The above is an example of how to implement it, and perhaps how it would have to be defined in the official language specs. The language reference manual can simply say that "expr relop expr relop ... relop expr" works the way a mathematician might expect, and the whole construct returns a single boolean.) Karl W. Z. Heuer (ima!haddock!karl or karl@haddock.isc.com), The Walking Lint
mwm@eris.berkeley.edu (Mike (I'll think of something yet) Meyer) (08/14/89)
I've been following this, wondering if someone form the Icon group
would speak up. Since nobody has, and Karl came close to their
solution, I'll put an oar in...
In article <14278@haddock.ima.isc.com> karl@haddock.ima.isc.com (Karl Heuer) writes:
<Okay, then, here's one way to parse such constructs. A comparison operator
<like "a < b" returns an object of an internal type "cascadable boolean", whose
<value is either {FALSE} or {TRUE, b}. If a cascadable boolean is used in any
<context other than the left operand of a compare, it immediately decays
<into a normal boolean. If it is the left operand of a compare, then
<"{FALSE} < c" returns {FALSE} (but should probably still evaluate c for side
<effects), while "{TRUE, b} < c" returns the same object as "b < c" (another
<cascadable boolean).
The Icon group find a slightly cleaner way to do this. Instead of
expression evalutaing to booleans, they either produce a value, or
"fail". Any expressions including a failed expression also fail, except
for "not" (which is classed as a control structure). If the expression
fed to not fails, then it returns a null value; otherwise, it fails.
Control constructs treat failed expressions as false, and valued
expressions as true. Relops are handled roughly as above, except that
where they return the value of the right-hand operand or fail. So that
if a < b < c < d then
Will work as you'd expect - succeeding only if all the comparisons are
true. Likewise for:
if a < b <= c = d < e then
etc, etc, etc.
I found this feature quite nice, and easy to work with. The concept of
"failure" also has interesting implications elsewhere, and works well
with the rest of the language.
The reference is "The Icon Programming Language", by Griswold &
Griswold. You can get Icon by ftp from several sites on the internet.
<mike
--
Tell me how d'you get to be Mike Meyer
As beautiful as that? mwm@berkeley.edu
How did you get your mind ucbvax!mwm
To tilt like your hat? mwm@ucbjade.BITNET
peter@ficc.uu.net (Peter da Silva) (08/14/89)
In article <14278@haddock.ima.isc.com>, karl@haddock.ima.isc.com (Karl Heuer) writes: > Okay, then, here's one way to parse such constructs. [ complex explanation of run-time evaluation of !a < b <= c! using pairs of values ] Well, that's one way of implementing the run-time code. Doesn't say anything about parsing it, though. Parsing is easy... in yacc you'd do something like this: boolean : expression | boolean relop expression ; In a recursive-descent parser: parse_relop() /* Called on seeing a relation operator */ { while(is_relop(next_token)) { shift(); expression(); } } Code generation, now. You want to end up with something like this: For the expression !a < b <= c!... evaluate A evaluate B cmp A,B bge FAIL evaluate C, with A possibly scratched. cmp B,C ble SUCCEED FAIL: action on failure (go to end of if stmt, push 0, whatever) ... SUCCEED:action on success (may be inside if stmt, push 1, whatever) For a stupid stack machine compiler, putting it in the RD parser above: parse_relop() { LABEL fail = genlab(); LABEL succeed = genlab(); LABEL end = genlab(); while(1) { TOKEN saved; saved = next_token; shift(); expression(); if(is_relop(next_token)) { gen(SAVE_TOP); /* copies top under second */ gen_branch(reverse_sense(saved), fail); continue; } else { gen_branch(saved, succeed); break; } } gen_target(fail); gen_push(FALSE); gen_branch(always, end); gen_target(succeed); gen_push(TRUE); gen_target(end); } You will note that there is considerable room for optimisation :->. -- Peter da Silva, Xenix Support, Ferranti International Controls Corporation. Business: peter@ficc.uu.net, +1 713 274 5180. | "The sentence I am now Personal: peter@sugar.hackercorp.com. `-_-' | writing is the sentence Quote: Have you hugged your wolf today? 'U` | you are now reading"
dave@PRC.Unisys.COM (David Lee Matuszek) (08/15/89)
In article <178@enea.se> sommar@enea.se (Erland Sommarskog) writes: >I think John Lacey (lacey@tcgould.tn.cornell.edu) said this: >>The parse would be more difficult. The problems aren't analogous. The >>dangling-else problem is one of ambiguity. Parsing a general relational >>expression is difficult because the same string will be used for multiple >>tokens. For example, in (a < x < b), x has to be associated separately >>to its left and right. > >I have to object here. Way back at the university I took a compiler >course. In the tiny language I made for my assignment I defined the >grammar relational expression something like: > rel_exp ::= exp (rel_op exp)* >()* meaning 1 or more times easy. Trivial, isn't it? The semantic >interpretation was AND. I.e. 0 < x < 10 was interpreted as (0 < x) >AND (x < 10), which seems as the natural interpretation for the >case you would like to use it for. A thing like > a = b <= z > y < b >wouldn't something to recommend but the langauge dealt with it the same >way. > >Actually I have always been surprised that no language I have dealt >have had this feature since it is so easy to implement. Am I overlook- >ing something? >-- Sorry for the long insertion, but context is important. A couple of years ago I developed a small special-purpose language for the project I was involved in. One of the things I did was to implement extended relational expressions such as described above. I wrote both an interpreter and a compiler for the language, and it got a fair amount of use. It wasn't hard. I don't think you're overlooking anything. I had no trouble at all with that part of the language. You do have to decide what to do about expressions such as "x < (y < z)" ["illegal" is a good choice!]. I don't think it would be a good idea to try to extend C in this way, since x < y has an interpretation that only a hacker could love (an integer rather than a truth value), but Pascal-like languages are no problem. Like you, I don't know why more languages don't have this perfectly natural construct. BTW, I also implemented all <variable> in <set or list> satisfy <logical expression> each <variable> in <set or list> satisfies <logical expression> some <variable> in <set or list> satisfies <logical expression> (The first two are just syntactic variants of each other.) I also meant to add the following, but never got around to it: no <variable> in <set or list> satisfies <logical expression> The <variable> is used in the logical expression; if "all/each" or "no" fails, or if "some" succeeds, the <variable> retains the (first) value that caused this to happen, otherwise the <variable> is undefined. These aren't hard either, and save the programmer from explicitly writing loops for some common cases. I think these are not common because Pascal-like languages do not generally have sets or lists as supported data types. -- Dave Matuszek (dave@prc.unisys.com) -- Unisys Corp. / Paoli Research Center / PO Box 517 / Paoli PA 19301 -- Any resemblance between my opinions and those of my employer is improbable. Remember, too, that 1989 is the 17th anniversary of the LAST man on the moon.
firth@sei.cmu.edu (Robert Firth) (08/15/89)
In article <178@enea.se> sommar@enea.se (Erland Sommarskog) writes: [ allowing 'x<y<z' to mean 'x<y & y<z'] >Actually I have always been surprised that no language I have dealt >have had this feature since it is so easy to implement. Am I overlook- >ing something? The above is a feature of the language BCPL. In simple cases, it works very well indeed: if 'A' <= ch <= 'Z' do ... In complicated cases, it can trip you up: if x < f() < y do ... might call f() once or twice, for reasons difficult to explain to a beginner. And beginners have this habit of trying complicated cases, rather the way kittens like ravelling string.
lacey@batcomputer.tn.cornell.edu (John Lacey) (08/15/89)
In talking about _Real Conditionals_ :), In article <3829@bd.sei.cmu.edu> of comp.lang.misc firth@sei.cmu.edu (Robert Firth) writes: } The above is a feature of the language BCPL. In simple cases, it } works very well indeed: } } if 'A' <= ch <= 'Z' do ... } } In complicated cases, it can trip you up: } } if x < f() < y do ... } } might call f() once or twice, for reasons difficult to explain to a } beginner. And beginners have this habit of trying complicated cases, } rather the way kittens like ravelling string. Then, the above is _not_ a feature of BCPL. However, you weren't expected to know that, unless you have been following this thread from comp.lang.c . The original question (_way_ back) was a open switch statement that allowed arbitrary expressions, and picked the path of one that is true (aka Dijkstra's if-fi construct) and also *evaluated each expression only once*. That last is the key. Then we moved to simply getting full blown conditionals, like those in mathematics. If (x < f() < y) ever has side effects problems in math., I should change majors or something, 'cause it's time to get out. :-) So far, Lisp, Icon, and BCPL have all tried and failed to meet the challenge (Icon came PDClose). Any more takers? -- John Lacey lacey@tcgould.tn.cornell.edu cornell!batcomputer!lacey After August 16: jjlacey@owucomcn.bitnet If you have to, try mdl@sppy00.UUCP or maybe {...}!osu-cis!sppy00!mdl
db@lfcs.ed.ac.uk (Dave Berry) (08/15/89)
In article <1989Aug14.022903.22953@agate.berkeley.edu> mwm@eris.berkeley.edu (Mike Meyer) writes: > >The Icon group find a slightly cleaner way to do this. Instead of >expression evalutaing to booleans, they either produce a value, or >"fail". Any expressions including a failed expression also fail, except >for "not" (which is classed as a control structure). > >Likewise for: > > if a < b <= c = d < e then What about (a < b) = (d < e), i.e. comparing results of relational operations? Presumably this is equivalent to if a < b and d < e then b = e [else fail] and not to the expected result from boolean logic. Or does bracketing a relational expression force it to produce a canonical truth value (ugh) ? 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 Rhetoric 101: Use of "scare" quotes and the phrase "so-called".
peter@ficc.uu.net (Peter da Silva) (08/15/89)
In article <3829@bd.sei.cmu.edu>, firth@sei.cmu.edu (Robert Firth) writes: > The above is a feature of the language BCPL... > if x < f() < y do ... > might call f() once or twice, for reasons difficult to explain to a > beginner. Every now and then I read about something that gives me the same sensation as discovering a hole in a baby-wipe when changing a soiled daiper. If the language is designed so that f() can be called twice, then that is a design flaw. Boy, I'm glad they didn't write UNIX at Cambridge. -- Peter da Silva, Xenix Support, Ferranti International Controls Corporation. Business: peter@ficc.uu.net, +1 713 274 5180. | "The sentence I am now Personal: peter@sugar.hackercorp.com. `-_-' | writing is the sentence Quote: Have you hugged your wolf today? 'U` | you are now reading"
peter@ficc.uu.net (Peter da Silva) (08/15/89)
In article <8620@batcomputer.tn.cornell.edu>, lacey@batcomputer.tn.cornell.edu (John Lacey) writes: > So far, Lisp, Icon, and BCPL have all tried and failed to meet the challenge > (Icon came PDClose). Any more takers? The Hydril Smart RTU programming language. a < b < c Evaluated TRUE if a < b && b < c, FALSE otherwise. No expression is evaluated more than once. If a >= b, then c is not evaluated at all (lazy evaluation). Any sequence of expressions followed by relational operators were valid. -- Peter da Silva, Xenix Support, Ferranti International Controls Corporation. Business: peter@ficc.uu.net, +1 713 274 5180. | "The sentence I am now Personal: peter@sugar.hackercorp.com. `-_-' | writing is the sentence Quote: Have you hugged your wolf today? 'U` | you are now reading"
nevin1@cbnewsc.ATT.COM (nevin.j.liber) (08/16/89)
In article <178@enea.se> sommar@enea.se (Erland Sommarskog) writes: >Actually I have always been surprised that no language I have dealt >have had this feature since it is so easy to implement. Am I overlook- >ing something? There are a few things. In evaluating the following expression: a < b < c < ... < n where a,b,c,...,n are arbituary EXPRESSIONS which *may have side effects* (something which mathematicians using this notation don't normally deal with), these are some of the issues which arise: Is the order of evaluation left to right, right to left, or arbituary? If "a < b" is false, is c necessarily still evaluated? Are a,b,c,...,n each evaluated only once, at most once, or as many times as necessary? The answers to these questions have a profound effect on the spirit of the language, the style of code written in the language, the implementation of the language, the possible optimisations for the language, etc. Different languages will have different answers to these questions (as well as the question "Does this construct really fit in with the rest of the language?"). Although at a first pass it is easy to implement, the real question becomes "Will this construct be truly beneficial to the language?" Or, rephrasing this question pessimistically, "Overall, will this construct be detrimental to the language?" -- _ __ NEVIN ":-)" LIBER nevin1@ihlpb.ATT.COM (312) 979-4751 IH 4F-410 ' ) ) "We are almost into the '90s; *nothing* is wierd." / / _ , __o ____ -- Buzz Kelman, Newsman & Bluesman, WLUP, 7/28/89 / (_</_\/ <__/ / <_ As far as I know, these are NOT the opinions of AT&T.
nevin1@cbnewsc.ATT.COM (nevin.j.liber) (08/16/89)
In article <5689@ficc.uu.net> peter@ficc.uu.net (Peter da Silva) writes: |In article <3829@bd.sei.cmu.edu>, firth@sei.cmu.edu (Robert Firth) writes: |> if x < f() < y do ... |> might call f() once or twice, for reasons difficult to explain to a |> beginner. |If the language is designed so that f() can be called twice, |then that is a design flaw. But is f() even called once?? Suppose x=1 and y=0. I do the x<y comparison first. Since I now know that the entire expression is false, should I bother to evaluate f()? I can see arguments both ways; either decision will have a profound effect on the resulting language. -- _ __ NEVIN ":-)" LIBER nevin1@ihlpb.ATT.COM (312) 979-4751 IH 4F-410 ' ) ) "We are almost into the '90s; *nothing* is wierd." / / _ , __o ____ -- Buzz Kelman, Newsman & Bluesman, WLUP, 7/28/89 / (_</_\/ <__/ / <_ As far as I know, these are NOT the opinions of AT&T.
peter@ficc.uu.net (Peter da Silva) (08/16/89)
In article <2452@cbnewsc.ATT.COM>, nevin1@cbnewsc.ATT.COM (nevin.j.liber) writes: > In article <5689@ficc.uu.net> peter@ficc.uu.net (Peter da Silva) writes: > |In article <3829@bd.sei.cmu.edu>, firth@sei.cmu.edu (Robert Firth) writes: [ in BCPL ] > |> if x < f() < y do ... > |> might call f() once or twice, for reasons difficult to explain to a > |> beginner. > |If the language is designed so that f() can be called twice, > |then that is a design flaw. > But is f() even called once?? In this case, yes. If it's !x < y < f() < z!, then maybe not. > Suppose x=1 and y=0. I do the x<y > comparison first. Why? You don't know that the language specifies that this statement makes any assumptions about x relative to y. I know BCPL doesn't, and that's the language we're immediately referencing. > I can see arguments both ways; either > decision will have a profound effect on the resulting language. Vice-versa, the language will have a profound effect on the decision. -- Peter da Silva, Xenix Support, Ferranti International Controls Corporation. Business: peter@ficc.uu.net, +1 713 274 5180. | "The sentence I am now Personal: peter@sugar.hackercorp.com. `-_-' | writing is the sentence Quote: Have you hugged your wolf today? 'U` | you are now reading"
sommar@enea.se (Erland Sommarskog) (08/18/89)
David Lee Matuszek (dave@PRC.Unisys.COM) writes: >I don't think you're overlooking anything. I had no trouble at all >with that part of the language. You do have to decide what to do >about expressions such as "x < (y < z)" ["illegal" is a good choice!]. In Pascal x < (y < z) is perfectly legal if x is boolean. As far as over-looking, I can only think one thing and that is expressions like a < b < f(). Should f always be called? Well, the easy answer is that such a think is not defined by the language and any program that relies on that f is always called (or only called when necessary) is clearly erroneous. >I think these are not >common because Pascal-like languages do not generally have sets or >lists as supported data types. Almost true. Pacal itself has sets though. -- Erland Sommarskog - ENEA Data, Stockholm - sommar@enea.se "Hey poor, you don't have to be Jesus!" - Front 242
gudeman@arizona.edu (David Gudeman) (08/18/89)
In article <1989Aug14.022903.22953@agate.berkeley.edu> mwm@eris.berkeley.edu (Mike (I'll think of something yet) Meyer) writes: [summary: in Icon, (1) a relational operator "fails" if the relation does not hold, and produces the value of the right operand if the relation holds. (2) if one argument to an operation fails, the whole operation fails. (3) conditional contexts like "if <cond> then" and "while <cond> do" use failure as false, and any value as "true".] > > if a < b < c < d then > >Will work as you'd expect - succeeding only if all the comparisons are >true. Likewise for: > > if a < b <= c = d < e then This mechanism has much more far-reaching consequences that just allowing relational operators to "cascade" properly. Here are a couple of other Icon expressions: i := (i < j) # assign j to i only if i is less than j # the | symbol returns the results of both operands, one at a time if f(i) < (j | k) then ... # if result of f(i) is less than j or k then ... -- David Gudeman Department of Computer Science The University of Arizona gudeman@arizona.edu Tucson, AZ 85721 {allegra,cmcl2,ihnp4,noao}!arizona!gudeman
gudeman@arizona.edu (David Gudeman) (08/20/89)
In article <8620@batcomputer.tn.cornell.edu> lacey@batcomputer.tn.cornell.edu (John Lacey) writes: >In talking about _Real Conditionals_ :), >... Then we moved to simply getting full blown conditionals, like >those in mathematics. If (x < f() < y) ever has side effects problems in >math., I should change majors or something, 'cause it's time to get out. :-) > >So far, Lisp, Icon, and BCPL have all tried and failed to meet the challenge >(Icon came PDClose). Any more takers? Urr. I thought both Lisp and Icon succeeded. They both evaluate each argument exactly once and produce a conditional result that is true exactly when the corresponding value in math is true. Are you complaining about the fact that those languages don't use boolean values? (Lisp uses NIL/non-NIL and Icon uses failure/success). If so, I should point out that math doesn't use boolean values as the result of (in)equalities either. In math the (in)equality is just an assertion that tells something about the variables in the equation, but in functional/procedural programming languages, (in)equalities are only used as controls for conditional structures, and they work fine in both Lisp and Icon. To be _really_ math-like the expression (i < j < k) should create a condition on i, j, and k such the relation holds. If this is impossible due to other constraints, then the program should say that there is a contradiction. Icon actually comes closer to this than a language with boolean results would. -- David Gudeman Department of Computer Science The University of Arizona gudeman@arizona.edu Tucson, AZ 85721 {allegra,cmcl2,ihnp4,noao}!arizona!gudeman
gudeman@arizona.edu (David Gudeman) (08/22/89)
In article <126@castle.ed.ac.uk> db@lfcs.ed.ac.uk (Dave Berry) writes: >[in Icon]... >What about (a < b) = (d < e), i.e. comparing results of relational >operations? ... >and not to the expected result from boolean logic. Or does bracketing >a relational expression force it to produce a canonical truth value (ugh) ? No. Icon doesn't have anything resembling a boolean type. I might point out that the expression (a < b) = (d < e) is from _extremely_ obscure boolean logic, not from common high school algebra. No one would know what to do with it except digital engineers, mathematicians and Pascal programmers. Icon was written for a larger audience. And furthermore, #include <soapbox.bool> Boolean algebra is an inelegant hack in programming languages. Programming languages should either restrict relations to conditional contexts (ick) or find an interesting and useful purpose for relationals outside of conditional contexts (like C, Lisp, and Icon have done). Actually, boolean algebra is an attempt at the second option, but a failed one. Why use a trivial domain like truth values when it can easily be subsumed into a larger, more interesting domain? -- David Gudeman Department of Computer Science The University of Arizona gudeman@arizona.edu Tucson, AZ 85721 {allegra,cmcl2,ihnp4,noao}!arizona!gudeman
db@lfcs.ed.ac.uk (Dave Berry) (08/31/89)
In article <13359@megaron.arizona.edu> gudeman@arizona.edu (David Gudeman) writes: >In article <8620@batcomputer.tn.cornell.edu> lacey@batcomputer.tn.cornell.edu (John Lacey) writes: >>In talking about _Real Conditionals_ :), >>So far, Lisp, Icon, and BCPL have all tried and failed to meet the challenge > >Urr. I thought both Lisp and Icon succeeded. They both evaluate each >argument exactly once and produce a conditional result that is true >exactly when the corresponding value in math is true. I agree about Icon, but are you sure about Lisp? I thought that (< a b) returned either t or nil. If so, although it can handle cases like (< a b c d), it can't handle (<= (< a b) c). Any functional language can write the equivalent of (< a b c d). 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."
gateley@m2.csc.ti.com (John Gateley) (09/01/89)
In article <282@castle.ed.ac.uk> db@lfcs.ed.ac.uk (Dave Berry) writes: >In article <13359@megaron.arizona.edu> gudeman@arizona.edu (David Gudeman) writes: >>In article <8620@batcomputer.tn.cornell.edu> lacey@batcomputer.tn.cornell.edu (John Lacey) writes: >>>In talking about _Real Conditionals_ :), >>>So far, Lisp, Icon, and BCPL have all tried and failed to meet the challenge >> >>Urr. I thought both Lisp and Icon succeeded. [...] >I agree about Icon, but are you sure about Lisp? I thought that >(< a b) returned either t or nil. If so, although it can handle >cases like (< a b c d), it can't handle (<= (< a b) c). First, do (setf (symbol-function '<=help) (symbol-function '<=)) for all the relational predicates. Next define a macro: (defmacro <= (&rest args) (let ((result (tree-walk args))) result)) and so on for all the relational predicates. Here, treewalk is a function which basically restructures the input so that nested relations are handled properly: for example (<= (< a b) c) means (let ((b-temp b)) (and (< a b-temp) (<= b-temp c)). Cautions: this may not work someday in CL, as I think the cleanup committee decided that lisp: functions may not be redefined. Also, if it does work it may cause a performance hit since the compiler might have special knowledge about <= and friends. So, Lisp succeeds. The macro facility in Lisp gives you the ability to model just about any programming syntax you want (within the inherent bounds of lisp syntax). John gateley@m2.csc.ti.com
kirshenb@hplabsb.HP.COM (Evan Kirshenbaum) (09/06/89)
In article <89723@ti-csl.csc.ti.com> gateley@m2.UUCP (John Gateley) writes: >In article <282@castle.ed.ac.uk> db@lfcs.ed.ac.uk (Dave Berry) writes: >>In article <13359@megaron.arizona.edu> gudeman@arizona.edu (David Gudeman) writes: >>>In article <8620@batcomputer.tn.cornell.edu> lacey@batcomputer.tn.cornell.edu (John Lacey) writes: >>>>In talking about _Real Conditionals_ :), >>>>So far, Lisp, Icon, and BCPL have all tried and failed to meet the challenge >>> >>>Urr. I thought both Lisp and Icon succeeded. [...] >>I agree about Icon, but are you sure about Lisp? I thought that >>(< a b) returned either t or nil. If so, although it can handle >>cases like (< a b c d), it can't handle (<= (< a b) c). In scheme, one should be able to do something of the form: (extend-syntax (order) ((order) '#!true) ((order a op b more ...) (with ((temp (gensym))) (let ((temp b)) (and (op a temp) (order temp more ...)))))) which would allow you to write infix relations of the form (order a < b >= c != d = e divides f) This allows any binary operation to be used as an operator, and should be trivially optimized by the compiler. Evan Kirshenbaum HP Laboratories 3500 Deer Creek Road, Building 26U Palo Alto, CA 94304 kirshenbaum@hplabs.hp.com (415)857-7572
kirshenb@hplabsb.HP.COM (Evan Kirshenbaum) (09/06/89)
In article <5410@hplabsb.HP.COM> kirshenb@hplabsb.UUCP (Evan Kirshenbaum) makes a boo-boo: >In scheme, one should be able to do something of the form: > >(extend-syntax (order) > ((order) '#!true) should be: ((order a) '#!true) > ((order a op b more ...) > (with ((temp (gensym))) > (let ((temp b)) > (and (op a temp) > (order temp more ...)))))) > Evan Kirshenbaum HP Laboratories 3500 Deer Creek Road, Building 26U Palo Alto, CA 94304 kirshenbaum@hplabs.hp.com (415)857-7572