1. A bug in the interpreter

I was experimenting with some code recently, when I discovered a bug in the
parser.
The following code will parse without complaint, but does not work properly.
include get.e
integer ch

for n = 1 to 10 do
   if 4 < n < 8 then
      ? n
   end if
end for

ch = wait_key()

This program should display the numbers 5,6,and 7.
It actually displays the number 1 through 10.

The problem is with function rexpr() in parser.e which parses the expression 4 <
n < 8.
If the value of n is 1, it calcualtes 4 < 1 which is FALSE.
It then calculates FALSE < 8 which is meaningless because FALSE is not a number.
Because TRUE and FALSE are represented by the numbers 1 and 0, the computer can
perform the calcualtion.
And because both 0 and 1 are less than 8, the expression will evaluate to TRUE
no matter what value n contains.

Here's a modified version of function rexpr() I believe will correct the
problem.
It requires the procedure TempKeep() in emit.e be made global.
function rexpr()
   token tok
   integer id, opnd
   sequence patches
   patches = {}
   tok = cexpr()
   if tok[T_ID] <= GREATER and tok[T_ID] >= LESS then
      id = tok[T_ID]
      tok = cexpr()
      emit_op(id)
opnd = Code[$-1] -- preserve the previous rhs value to be used as the next
      lhs value
      if tok[T_ID] <= GREATER and tok[T_ID] >= LESS then
         TempKeep(opnd)
         if short_circuit then
            emit_op(SC1_AND)
            patches &= length(Code)
            emit_addr(0)
         end if
      end if
      while tok[T_ID] <= GREATER and tok[T_ID] >= LESS do
         id = tok[T_ID]
         emit_opnd(opnd) -- push operand onto cg_stack
         tok = cexpr() -- get next operand
         emit_op(id)
         if short_circuit then
            emit_op(SC2_NULL)
         end if
         opnd = Code[$-1]
         if tok[T_ID] <= GREATER and tok[T_ID] >= LESS then
            TempKeep(opnd)
            if short_circuit then
               emit_op(SC1_AND)
               patches &= length(Code)
               emit_addr(0)
            end if
         end if
         if not short_circuit then
            emit_op(AND)
         end if
      end while
      opnd = Code[$]
      for n = 1 to length(patches) do
         backpatch(patches[n],opnd)
         backpatch(patches[n]+1,length(Code)+1)
      end for
   end if
   return tok
end function

Thanks Daryl Border

new topic     » topic index » view message » categorize

2. Re: A bug in the interpreter

Daryl Border wrote:
> 
> I was experimenting with some code recently, when I discovered a bug in the
> parser.
> The following code will parse without complaint, but does not work properly.
>
> include get.e
> integer ch
> 
> for n = 1 to 10 do
>    if 4 < n < 8 then
>       ? n
>    end if
> end for
> 
> ch = wait_key()
>

In Euphoria, you have to do it this way:

   if 4 < n and n < 8 then

-=ck
"Programming in a state of Euphoria."
http://www.cklester.com/euphoria/

new topic     » goto parent     » topic index » view message » categorize

3. Re: A bug in the interpreter

Darly Border wrote:

>I was experimenting with some code recently, when I discovered a
>bug in the parser. The following code will parse without
>complaint, but does not work properly.
>
>for n = 1 to 10 do
>   if 4 < n < 8 then
>      ? n
>   end if
>end for
>
>This program should display the numbers 5,6,and 7. It actually
>displays the number 1 through 10.
>
>The problem is with function rexpr() in parser.e which parses
>the expression 4 < n < 8. If the value of n is 1, it calcualtes
>4 < 1 which is FALSE. It then calculates FALSE < 8 which is
>meaningless because FALSE is not a number. Because TRUE and
>FALSE are represented by the numbers 1 and 0, the computer can
>perform the calcualtion. And because both 0 and 1 are less than
>8, the expression will evaluate to TRUE no matter what value n
>contains.

While I think "4 < n < 8" is a nice shortcut, what about
"(4 < n) < 8"?  It is also accepted by Euphoria.  How should it
be evaluated?

Perhaps a question to ask is are Euphoria expressions meant to be
more C-like or Pascal-like.  Or something in between?  Something
entirely different?

C will accept both of the above expressions, but will evaluate
both as the latter expression, where "4 < n" returns a 0 or 1
depending on the truth value of the expression.  Basically the
way Euphoria is evaluating it now.

Pascal will accept neither expression, because relational
operators require an integer expression, and "4 < n" is a boolean
expression, parenthesized or not.

It would be kind of cool if Euphoria could properly handle "4 < n
< 8", but you'd have to define 'properly', and you'd also have to
have special code for "(4 < n) < 8", so that the relational
operators behaved consistently.

I think it would bother me if Euphoria handled "4 < n < 8"
'properly' (e.g., not as it does now), but continued to support
"(4 < n) < 8".  That seems awfully inconsistent.

I think the viable solutions are:

1) Leave it the way it is.  It might be nice to document the
behavior.  Essentially C-like behavior.

2) Make expressions more Pascal-like, and thus prohibit "4 < n <
8" and "(4 < n) < 8" altogether.  The former expression is easy
to prohibit via a grammar change.  The latter would require
expressions to be typed as number vs. boolean. This might be a
lot of work, and it might introduce unwanted side effects.

3)  Make "4 < n < 8" work the way a non-C programmer thinks it
should work, e.g., "4 < n" and "n < 8".  And then prohibit "(4 <
n) < 8", as it would make no sense anymore.  You've already
solved the first problem.  However, as in number 2 above,
prohibiting the latter expression might be a lot of work, and it
might introduce unwanted side effects.

This reminds me of a question I've had:  is there an official
Euphoria grammar?

new topic     » goto parent     » topic index » view message » categorize

4. Re: A bug in the interpreter

Ed Davis wrote:
> 
> Darly Border wrote:
> 
> >I was experimenting with some code recently, when I discovered a
> >bug in the parser. The following code will parse without
> >complaint, but does not work properly.
> >
> >for n = 1 to 10 do
> >   if 4 < n < 8 then
> >      ? n
> >   end if
> >end for
> >
> >This program should display the numbers 5,6,and 7. It actually
> >displays the number 1 through 10.
> >
> >The problem is with function rexpr() in parser.e which parses
> >the expression 4 < n < 8. If the value of n is 1, it calcualtes
> >4 < 1 which is FALSE. It then calculates FALSE < 8 which is
> >meaningless because FALSE is not a number. Because TRUE and
> >FALSE are represented by the numbers 1 and 0, the computer can
> >perform the calcualtion. And because both 0 and 1 are less than
> >8, the expression will evaluate to TRUE no matter what value n
> >contains.
> 
> While I think "4 < n < 8" is a nice shortcut, what about
> "(4 < n) < 8"?  It is also accepted by Euphoria.  How should it
> be evaluated?
> 
> Perhaps a question to ask is are Euphoria expressions meant to be
> more C-like or Pascal-like.  Or something in between?  Something
> entirely different?
> 
> C will accept both of the above expressions, but will evaluate
> both as the latter expression, where "4 < n" returns a 0 or 1
> depending on the truth value of the expression.  Basically the
> way Euphoria is evaluating it now.
> 
> Pascal will accept neither expression, because relational
> operators require an integer expression, and "4 < n" is a boolean
> expression, parenthesized or not.
> 
> It would be kind of cool if Euphoria could properly handle "4 < n
> < 8", but you'd have to define 'properly', and you'd also have to
> have special code for "(4 < n) < 8", so that the relational
> operators behaved consistently.
> 
> I think it would bother me if Euphoria handled "4 < n < 8"
> 'properly' (e.g., not as it does now), but continued to support
> "(4 < n) < 8".  That seems awfully inconsistent.
> 
> I think the viable solutions are:
> 
> 1) Leave it the way it is.  It might be nice to document the
> behavior.  Essentially C-like behavior.
> 
> 2) Make expressions more Pascal-like, and thus prohibit "4 < n <
> 8" and "(4 < n) < 8" altogether.  The former expression is easy
> to prohibit via a grammar change.  The latter would require
> expressions to be typed as number vs. boolean. This might be a
> lot of work, and it might introduce unwanted side effects.
> 
> 3)  Make "4 < n < 8" work the way a non-C programmer thinks it
> should work, e.g., "4 < n" and "n < 8".  And then prohibit "(4 <
> n) < 8", as it would make no sense anymore.  You've already
> solved the first problem.  However, as in number 2 above,
> prohibiting the latter expression might be a lot of work, and it
> might introduce unwanted side effects.
> 
> This reminds me of a question I've had:  is there an official
> Euphoria grammar?

Ed, 
   It is not the responsibility of the interpreter to prevent the programmer
from using poorly formed expressions such as (4 < n) < 8. It is the
responsibility
of the interpreter to evaluate the expressions according to the rules of
mathmatics. My code evaluates both expressions correctly. Euphoria currently
does not.
Daryl Border

new topic     » goto parent     » topic index » view message » categorize

5. Re: A bug in the interpreter

Mathematically, 4 < n < 8 should evaluate to 4 < n and n < 8. Euphoria should
develop to reflect this as it is "correct".

(4 < n) < 8 is different - as I see it.

If n = 32,
(4 < n) < 8 = TRUE < 8 = 1 < 8 = TRUE which is incorrect!

Alex

new topic     » goto parent     » topic index » view message » categorize

6. Re: A bug in the interpreter

Alex Chamberlain wrote:
> 
> Mathematically, 4 < n < 8 should evaluate to 4 < n and n < 8. Euphoria
> should develop to reflect this as it is "correct".
> 
> (4 < n) < 8 is different - as I see it.
> 
> If n = 32,
> (4 < n) < 8 = TRUE < 8 = 1 < 8 = TRUE which is incorrect!
> 
> Alex

I understand the mathematics behind it, but it is just notation. I can't think
of any other common programming language that uses notation like this.

Most languages that I'm aware of require the keyword 'and' to disambiguate the
expression.

For the second example, the programmer needs to be aware that comparing TRUE and
8 has no mathematical meaning. Since Euphoria doesn't have built-in boolean types
the language just uses 1 and 0 as TRUE and FALSE. Some other languages use -1 and
0. Euphoria will also interpret any nonzero value as TRUE in the proper context.
Again, this is pretty standard behavior in programming languages. Or at least the
ones I'm familiar with (C and relatives, BASIC, Euphoria).

--
"Any programming problem can be solved by adding a level of indirection."
--anonymous
"Any performance problem can be solved by removing a level of indirection."
--M. Haertel
"Premature optimization is the root of all evil in programming."
--C.A.R. Hoare
j.

new topic     » goto parent     » topic index » view message » categorize

7. Re: A bug in the interpreter

Ed Davis wrote:
> This reminds me of a question I've had:  is there an official
> Euphoria grammar?

No there isn't.
Someone started to write one once, 
but I don't know if he finished it.
The syntax of Euphoria is simple enough that
I think most people can figure it out from
the reference manual, and now there's the PD source
to resolve any doubts.

Regards,
   Rob Craig
   Rapid Deployment Software
   http://www.RapidEuphoria.com

new topic     » goto parent     » topic index » view message » categorize

8. Re: A bug in the interpreter

Daryl Border

>   It is not the responsibility of the interpreter to prevent
>the programmer from using poorly formed expressions such as (4 <
>n) < 8.

Some people might say that "4 < n < 8" is a poorly formed
expression.  If you are coming from the C/Java world, you would
say it is perfectly valid, but it does not mean "4 < n and n <
8", but rather the (4 < n) < 8.

>It is the responsibility of the interpreter to evaluate the
>expressions according to the rules of mathmatics. My code
>evaluates both expressions correctly. Euphoria currently does
>not.

How does it correctly evaluate (4 < n) < 8?  Does it treat (4 <
n) as a boolean, and then compare against that?

What about "4 < n < 8 < a < b"?  How should that be evaluated? Is
it "4 < n and n < 8 and 8 < a and a < b?"  Should the interpreter
allow that? How do your changes evaluate it?

Along the same lines, what about:  "4 = n = 8"?  It is also
currently accepted, and apparently interpreted as:

(4 = n) = 8

The same way C would interpret it (well, replace the '=' with
'==').

Without understanding all the possible ramifications, I'm not
sure changing the current semantics is a good idea.

new topic     » goto parent     » topic index » view message » categorize

9. Re: A bug in the interpreter

Ed Davis wrote:
> 
> Daryl Border
> 
> >   It is not the responsibility of the interpreter to prevent
> >the programmer from using poorly formed expressions such as (4 <
> >n) < 8.
> 
> Some people might say that "4 < n < 8" is a poorly formed
> expression.  If you are coming from the C/Java world, you would
> say it is perfectly valid, but it does not mean "4 < n and n <
> 8", but rather the (4 < n) < 8.
> 
> >It is the responsibility of the interpreter to evaluate the
> >expressions according to the rules of mathmatics. My code
> >evaluates both expressions correctly. Euphoria currently does
> >not.
> 
> How does it correctly evaluate (4 < n) < 8?  Does it treat (4 <
> n) as a boolean, and then compare against that?

You are correct. (4 < n) < 8 is not a valid math expression. My code can't
evaluate it correctly because there is no valid way to evaluate it.
It would be nice if the interpreter could catch the error. But without a way
to distinguish between the integers 1 and 0  and the boolean values TRUE and
FALSE it can't. This problem already exists in euphoria, my code does not 
create it.

> 
> What about "4 < n < 8 < a < b"?  How should that be evaluated? Is
> it "4 < n and n < 8 and 8 < a and a < b?"  Should the interpreter
> allow that? How do your changes evaluate it?
> 
This is a valid math expression and your interpretation is correct. If my
code is bug free it will evaluate it correctly.

> Along the same lines, what about:  "4 = n = 8"?  It is also
> currently accepted, and apparently interpreted as:
> 
4 = n = 8 is a valid math expression and will be evaluated as 4 = n and n = 8.
It of course always evaluates to FALSE, but it is the programmer's
responsibility
to write useful code.

> (4 = n) = 8

Again (4 = n) = 8 is not a valid math expression because (4 = n) evaluates to
a boolean value.
> 
> The same way C would interpret it (well, replace the '=' with
> '==').
> 
> Without understanding all the possible ramifications, I'm not
> sure changing the current semantics is a good idea.

The problems you're concerned about already exist. Until a means to distinguish
between integers and boolean values is implimented, they will continue to exist.
In the mean time we will have to rely on the programmer's knowledge of math for
correct math expressions.
Daryl Border

new topic     » goto parent     » topic index » view message » categorize

10. Re: A bug in the interpreter

Ed Davis wrote:
> 
> Daryl Border
> 
> >   It is not the responsibility of the interpreter to prevent
> >the programmer from using poorly formed expressions such as (4 <
> >n) < 8.
> 
> Some people might say that "4 < n < 8" is a poorly formed
> expression.  If you are coming from the C/Java world, you would
> say it is perfectly valid, but it does not mean "4 < n and n <
> 8", but rather the (4 < n) < 8.
> 
> >It is the responsibility of the interpreter to evaluate the
> >expressions according to the rules of mathmatics. My code
> >evaluates both expressions correctly. Euphoria currently does
> >not.
> 
> How does it correctly evaluate (4 < n) < 8?  Does it treat (4 <
> n) as a boolean, and then compare against that?
> 
> What about "4 < n < 8 < a < b"?  How should that be evaluated? Is
> it "4 < n and n < 8 and 8 < a and a < b?"  Should the interpreter
> allow that? How do your changes evaluate it?
> 
> Along the same lines, what about:  "4 = n = 8"?  It is also
> currently accepted, and apparently interpreted as:
> 
> (4 = n) = 8
> 
> The same way C would interpret it (well, replace the '=' with
> '==').
> 
> Without understanding all the possible ramifications, I'm not
> sure changing the current semantics is a good idea.


One of the languages that has something similar is good old COBOL,
because you may omit the variable name in the second comparison,
but anyway it uses 'and'.
Anyway, I think the main issue is this: are there fixed rules for
the syntax and semantics of mathematical expressions? Newton,
Leibnitz, Fermat, Euler, Gauss, etc,. all of them used different
notations. What I was taught at school is now totally different.
And I see the time coming when mathematical notation will evolve
from computer programming languages.

Regards.

new topic     » goto parent     » topic index » view message » categorize

11. Re: A bug in the interpreter

Ricardo M. Forno wrote:
> One of the languages that has something similar is good old COBOL,
> because you may omit the variable name in the second comparison,
> but anyway it uses 'and'.
> Anyway, I think the main issue is this: are there fixed rules for
> the syntax and semantics of mathematical expressions? Newton,
> Leibnitz, Fermat, Euler, Gauss, etc,. all of them used different
> notations. What I was taught at school is now totally different.
> And I see the time coming when mathematical notation will evolve
> from computer programming languages.
> 
> Regards.

It is actually pretty simple. Given parentheses to group operations and the
precedence of operations, mathematical expressions are evaluated from left to
right. No operator in Euphoria is trinary; therefore expressions such as 4 < n <
8 are considered as two binary operations evaluated from left to right. First, 4
< n is evaluated then its result, 1 or 0, is compared to < 8.

Euphoria's precedence is found at http://www.rapideuphoria.com/refman_2.htm#2A

--
"Any programming problem can be solved by adding a level of indirection."
--anonymous
"Any performance problem can be solved by removing a level of indirection."
--M. Haertel
"Premature optimization is the root of all evil in programming."
--C.A.R. Hoare
j.

new topic     » goto parent     » topic index » view message » categorize

12. Re: A bug in the interpreter

Jason Gade wrote:
> 
> Ricardo M. Forno wrote:
> > One of the languages that has something similar is good old COBOL,
> > because you may omit the variable name in the second comparison,
> > but anyway it uses 'and'.
> > Anyway, I think the main issue is this: are there fixed rules for
> > the syntax and semantics of mathematical expressions? Newton,
> > Leibnitz, Fermat, Euler, Gauss, etc,. all of them used different
> > notations. What I was taught at school is now totally different.
> > And I see the time coming when mathematical notation will evolve
> > from computer programming languages.
> > 
> > Regards.
> 
> It is actually pretty simple. Given parentheses to group operations and the
> precedence
> of operations, mathematical expressions are evaluated from left to right. No
> operator
> in Euphoria is trinary; therefore expressions such as 4 < n < 8 are considered
> as two binary operations evaluated from left to right. First, 4 < n is
> evaluated
> then its result, 1 or 0, is compared to < 8.
> 
> Euphoria's precedence is found at <a
> href="http://www.rapideuphoria.com/refman_2.htm#2A">http://www.rapideuphoria.com/refman_2.htm#2A</a>
> 
> --
> "Any programming problem can be solved by adding a level of indirection."
> --anonymous
> "Any performance problem can be solved by removing a level of indirection."
> --M. Haertel
> "Premature optimization is the root of all evil in programming."
> --C.A.R. Hoare
> j.

Of course, Jason. I know this from the time I first programmed in C and
Euphoria.
It is really simple. Hovever, simpler than that is APL and J (do not confuse
with Java)
in which everything is evaluated from right to left, as assignment is evaluated.
My concern was not about Euphoria but about math itself. There is no undisputed
syntax / semantics for mathematical expressions. So it makes no sense to say,
for example, that Euphoria does not follow mathematical conventions, since
they are not uniform. For example, in algebra "ax" is usually interpreted as
"a times x", and not as a variable named "ax". Also, sometimes a dot was
used to mean "times", as in "a.x + c.y". The multiplication operator was
a sign resembling "x" and not "*" as in programming languages. There are also
a lot of strange symbols for square roots, derivatives, integrals, etc., for
which there is no equivalent in computer programming languages.

Regards.

new topic     » goto parent     » topic index » view message » categorize

13. Re: A bug in the interpreter

Ricardo M. Forno wrote:
> 
> Jason Gade wrote:
> > 
> > Ricardo M. Forno wrote:
> > > One of the languages that has something similar is good old COBOL,
> > > because you may omit the variable name in the second comparison,
> > > but anyway it uses 'and'.
> > > Anyway, I think the main issue is this: are there fixed rules for
> > > the syntax and semantics of mathematical expressions? Newton,
> > > Leibnitz, Fermat, Euler, Gauss, etc,. all of them used different
> > > notations. What I was taught at school is now totally different.
> > > And I see the time coming when mathematical notation will evolve
> > > from computer programming languages.
> > > 
> > > Regards.
> > 
> > It is actually pretty simple. Given parentheses to group operations and the
> > precedence
> > of operations, mathematical expressions are evaluated from left to right. No
> > operator
> > in Euphoria is trinary; therefore expressions such as 4 < n < 8 are
> > considered
> > as two binary operations evaluated from left to right. First, 4 < n is
> > evaluated
> > then its result, 1 or 0, is compared to < 8.
> > 
> > Euphoria's precedence is found at <a
> > href="http://www.rapideuphoria.com/refman_2.htm#2A">http://www.rapideuphoria.com/refman_2.htm#2A</a>
> > 
> > --
> > "Any programming problem can be solved by adding a level of indirection."
> > --anonymous
> > "Any performance problem can be solved by removing a level of indirection."
> > --M. Haertel
> > "Premature optimization is the root of all evil in programming."
> > --C.A.R. Hoare
> > j.
> 
> Of course, Jason. I know this from the time I first programmed in C and
> Euphoria.
> It is really simple. Hovever, simpler than that is APL and J (do not confuse
> with Java)
> in which everything is evaluated from right to left, as assignment is
> evaluated.
> My concern was not about Euphoria but about math itself. There is no
> undisputed
> syntax / semantics for mathematical expressions. So it makes no sense to say,
> for example, that Euphoria does not follow mathematical conventions, since
> they are not uniform. For example, in algebra "ax" is usually interpreted as
> "a times x", and not as a variable named "ax". Also, sometimes a dot was
> used to mean "times", as in "a.x + c.y". The multiplication operator was
> a sign resembling "x" and not "*" as in programming languages. There are also
> a lot of strange symbols for square roots, derivatives, integrals, etc., for
> which there is no equivalent in computer programming languages.
> 
> Regards.

I think you and I are in agreement. I may have replied to your post to make the
point to others. You make the exact point that I wanted to make -- namely that
there is more than one way in mathematics to symbolize an expression and there is
more than one way to symbolize it in the domain of programming languages.

You could say it is different in LISP and FORTH as well, which do not follow the
normal algebraic rules for expressions.

--
"Any programming problem can be solved by adding a level of indirection."
--anonymous
"Any performance problem can be solved by removing a level of indirection."
--M. Haertel
"Premature optimization is the root of all evil in programming."
--C.A.R. Hoare
j.

new topic     » goto parent     » topic index » view message » categorize

Search



Quick Links

User menu

Not signed in.

Misc Menu