HP Forums

Full Version: Somewhere between a bug or feature:
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
While working with a more complicated problem, I discovered this (a simple example):

[Entry Line]
b:=x^2;

a:=b|x=2; ---> x^2
-[but]-
a:=(b|x=2); ---> 4

While the behavior may be acceptable, remembering how the '|' (where) works is a little mind-tweaky, and it's history representation put a different spin even on that:

[History Screen]
(a:=b)|x=2 ----------- x^2
a:=b|x=2 ----------- 4

I'm not sure that it's worth discussing, but the way ()'s worked seemed a little peculiar. If one goes to the trouble of placing a constraint (substitution) on the underlying variable, it would seem that it was meant to be used in the solution. The result of either expression should have returned the numerical answer 4.
(11-13-2014 05:52 PM)DrD Wrote: [ -> ]While working with a more complicated problem, I discovered this (a simple example):

[Entry Line]
b:=x^2;

a:=b|x=2; ---> x^2
-[but]-
a:=(b|x=2); ---> 4

While the behavior may be acceptable, remembering how the '|' (where) works is a little mind-tweaky, and it's history representation put a different spin even on that:

[History Screen]
(a:=b)|x=2 ----------- x^2
a:=b|x=2 ----------- 4

I'm not sure that it's worth discussing, but the way ()'s worked seemed a little peculiar. If one goes to the trouble of placing a constraint (substitution) on the underlying variable, it would seem that it was meant to be used in the solution. The result of either expression should have returned the numerical answer 4.

I don't see any issues here (which doesn't mean there aren't issues). When assigning variables a value, any expression that needs to be evaluated first will be done prior to storing. So when you type:

a:=(b|x=2), you are storing the result of b|x=2 into the variable a. Of course, if b:=x^2, then b|x=2 will return 4, which is then stored into a. Basically the right hand side of ":=" is evaluated first prior to storing into a.

(a:=b)|x=2 means to substitute x=2 into (a:=b) except there is no x to substitute into because (a:=b) is not a mathematical expression or function; it's a calculator process for storing variables.

Edit: Typing in: a:=b|x=2 will result in (a:=b)|x=2. I would have expected the calculator to think a:=(b|x=2) and not (a:=b)|x=2

Edit again: a:=b|x=2 being treated as (a:=b)|x=2 is at least consistent with other similar input: x+x^2|x=2 is interpreted as (x+x^2)|x=2 and not x+(x^2|x=2).
A few more trials leads me to think that perhaps you're onto something.

b:=x^2;
b+2*x|x=3; --> x^2+6
b|x=3; ---> 9

I can't explain this.
(11-13-2014 10:43 PM)Han Wrote: [ -> ]A few more trials leads me to think that perhaps you're onto something.

b:=x^2;
b+2*x|x=3; --> x^2+6
b|x=3; ---> 9

I can't explain this.

How is this?

b(x):=x^2
b(x)+2*x|x=3 --> 15
(11-13-2014 11:31 PM)Mark Hardman Wrote: [ -> ]
(11-13-2014 10:43 PM)Han Wrote: [ -> ]A few more trials leads me to think that perhaps you're onto something.

b:=x^2;
b+2*x|x=3; --> x^2+6
b|x=3; ---> 9

I can't explain this.

How is this?

b(x):=x^2
b(x)+2*x|x=3 --> 15

That gets the job done if one wants to get the entire substitution. However, it does not explain how the | function has been implemented. In the case of b|x=3, the substitution seems to uncover one level of abstraction. That is, it substitutes x=2 into the value of b. On the other hand, b+2*x|x=3 only substitutes at face value to b+6, and then evaluates b+6 as x^2+6.
There is a indeed a difference between b|x=2 and b+x|x=2. The first argument of | is not evaled (otherwise the value of any identifier inside this expression would be replaced, including x in this example if x was assigned), but there is an exception: if the first argument is an identifier, it is replaced by its value (but the value is not evaled). The reason is that you have no reason to enter x|x=2 (2 is shorter) or b|x=2 (b would be shorter if it was not replaced).
[Entry Line] ................................ [History Screen]
b:=x^2;

I.) a:=b|x=2; ---> x^2 .......... (a:=b)|x=2 ----------- x^2

II.) a:=(b|x=2); ---> 4 ........... a:=b|x=2 ----------- 4

[Han]: When assigning variables a value, any expression that needs to be evaluated first will be done prior to storing. So when you type: a:=(b|x=2),
you are storing the result of b|x=2 into the variable a. Of course, if b:=x^2, then b|x=2 will return 4, which is then stored into a. Basically the right hand side of ":=" is evaluated first prior to storing into a.

[me]: I agree it should return 4, but the history represented it as x^2.

Case (I.):
Your Edit: Typing in: a:=b|x=2 will result in (a:=b)|x=2. I would have expected the calculator to think a:=(b|x=2) and not (a:=b)|x=2 Yes! Me, too!

For: a:=b|x=2, I expected b to be eval'ed with the | value. The resulting history representation implies, (to me), that a was replaced by b, due to the way it shows parens, but then ignored the | condition. If that behavior was wanted, why bother including the | suffix?

Case (II.):
To me, this is simply a more clearly represented intention of the desired order of eval, but has exactly the same result. So, I believe, the history representation is correct in it's behavior, revealing UNNECESSARY parens, but it REQUIRED the parens, in the entry line, in order to achieve the result. That would be the bug there.

Again, worthy of bugzilla food? I'm not really sure, but I tend to use the | operator a lot. It's consistent with my handwritten manner, but might not be as important to others. Also, I know de-buggers at hp are busy with more significant things. Having mentioned it, I've done my part and will leave it at that.

Thanks, Han, for collaboratively, elaborating!
Here's how I understand the where function (now).

1. Any expression in front of the | symbol is considered to be part of the expression that will be used for substitution, unless the user specifically adds in ()'s to limit the scope of the | operator. For example:

a+b^2|b=4 is treated as (a+b^2)|b=4

which makes sense to me as we would otherwise be forced to add in ()'s every time we use the | operator.

2. If the expression it a single variable that is defined, then the variable will be recalled, and this result is what becomes the expression for substitution. Otherwise, the expression is left as is.

restart;
b:=x^2;
b|x=2; --> 4

On the other hand,

a+b|x=2; --> a+x^2

There is nothing to substitute into a+b because rule #2 doesn't apply and there is no x in "a+b". Then a+b is evaluated to a+x^2 because b=x^2. We get the same result as if we only typed in a+b.

3. In the case of storing values via the := symbols, it is generally the case that the right hand side is evaluated first prior to storing. However, in conjunction with |, it appears that rule #1 above has higher priority. So typing a:=b|x=2 gets parsed as (a:=b)|x=2 (per rule #1). However, there is no x in the expression a:=b, so nothing is substituted. Finally, a:=b is passed for evaluation, which results in x^2 being stored into a. That is, (a:=b)|x=2 is no different from just typing a:=b as there is no x in "a:=b"

I am not sure I agree with this. I am of the opinion that the | operator should check for a valid "beginning" and not assume that the start of the entry line is the beginning. That is, the := should have higher priority than the | operation. That said, this comes down to a personal preference. When we start mixing actual mathematical operators (e.g. the | operator) with non-mathematical operators (e.g. :=), the question of which should have higher priority will never be truly sorted out to everyone's satisfaction. All we can expect is that the rules are consistent. In this case, it appears that they are.
I did mention it was a little "mind-tweaky." I'm thinking the heavier we are on the usage of parens, the better, where | is concerned, anyway.
Like in many other cases I think it increases clarity when we turn off Textbook Display for History, so uncheck Textbook Display in second page of Home Settings.

When we do this the substitution operation is always displayed in History with parentheses, in the form (argument | a=b), so we clearly see what we are doing.

Like Han pointed out ‘argument’ is generally not evaluated prior to substitution, apart from the exceptional case where ‘argument’ is a simple identifier which represents a variable containing an expression.

With simple identifier I mean that when ‘argument’ =k(1), k(1) is not evaluated prior to substitution.
k(1) can be the first element of a list.

This is often not what we expect, and therefore it can be a good idea to first store argument into a variable, say f, and then calculate (f |a=b).

Another possibility is to use subst(expression, a=b), which causes no problems.
(11-14-2014 05:18 PM)Han Wrote: [ -> ]Here's how I understand the where function (now).

1. Any expression in front of the | symbol is considered to be part of the expression that will be used for substitution, unless the user specifically adds in ()'s to limit the scope of the | operator. For example:

a+b^2|b=4 is treated as (a+b^2)|b=4

which makes sense to me as we would otherwise be forced to add in ()'s every time we use the | operator.

2. If the expression it a single variable that is defined, then the variable will be recalled, and this result is what becomes the expression for substitution. Otherwise, the expression is left as is.

restart;
b:=x^2;
b|x=2; --> 4

On the other hand,

a+b|x=2; --> a+x^2

There is nothing to substitute into a+b because rule #2 doesn't apply and there is no x in "a+b". Then a+b is evaluated to a+x^2 because b=x^2. We get the same result as if we only typed in a+b.

3. In the case of storing values via the := symbols, it is generally the case that the right hand side is evaluated first prior to storing. However, in conjunction with |, it appears that rule #1 above has higher priority. So typing a:=b|x=2 gets parsed as (a:=b)|x=2 (per rule #1). However, there is no x in the expression a:=b, so nothing is substituted. Finally, a:=b is passed for evaluation, which results in x^2 being stored into a. That is, (a:=b)|x=2 is no different from just typing a:=b as there is no x in "a:=b"

I am not sure I agree with this. I am of the opinion that the | operator should check for a valid "beginning" and not assume that the start of the entry line is the beginning. That is, the := should have higher priority than the | operation. That said, this comes down to a personal preference. When we start mixing actual mathematical operators (e.g. the | operator) with non-mathematical operators (e.g. :=), the question of which should have higher priority will never be truly sorted out to everyone's satisfaction. All we can expect is that the rules are consistent. In this case, it appears that they are.

I think the problem is that the calc. doesn't see b:=x^2 as a function, but only as an expression:
1. if you define b:=x^2, b is an expression not a function and b|x=2 --> 4
2. if you do a+b|x=2 --> x^2+a, but subst(a+b,x=2)--> a+4 because subst is for expressions.
3. if you do a+(b|x=2) --> a+4, correct answer.
4. if you define b(x):=x^2, define b as function, writing a+b(x)|x=2 --> a+4, but for functions the easier way is just to write a+b(2) --> a+4

So, when you write b:=x^2 the calc. does not see it as a function, but as an expression. You should use subst or enclose the expression in the parenthesis, in this case 'b|x=2' and all will be well. I think.
The where function | and the subst() function handle substitutions differently. The latter will resolve variables (and it would seem only one level deep) prior to substitution whereas the former does the reverse.

x:=a^2+1;
subst(x+1,x=1);
(x+1)|(x=2);
subst(x+1,a=1);
(x+1)|(a=1);

The only exception is the one pointed out by parisse earlier in the thread.
Reference URL's