The Assignment Principle

S

Stefan Ram

I once read the »Assignment Principle«. It says that after
an assignment a comparison with the assigned value yields
true. Assuming v was declared properly:

v = 2;
java.lang.System.out.println( v == 2 ); // prints true

I think we can assume a single thread of execution and
normal memory [not I/O registers or so]. Also, it is
about values and not expressions, so that

v = java.lang.Math.random();
java.lang.System.out.println( v == java.lang.Math.random() );

is not a counterexample.

Being cautious, I'd like to ask: Do you see any exceptions,
where this does not hold? (I suggest to reply only if the
answer to that question is »yes«.)
 
E

Eric Sosman

I once read the »Assignment Principle«. It says that after
an assignment a comparison with the assigned value yields
true. Assuming v was declared properly:

v = 2;
java.lang.System.out.println( v == 2 ); // prints true

I think we can assume a single thread of execution and
normal memory [not I/O registers or so]. Also, it is
about values and not expressions, so that

v = java.lang.Math.random();
java.lang.System.out.println( v == java.lang.Math.random() );

is not a counterexample.

Being cautious, I'd like to ask: Do you see any exceptions,
where this does not hold? (I suggest to reply only if the
answer to that question is »yes«.)

double x = Double.NaN;
assert x == NaN; // ka-BOOM!
 
M

markspace

Also, it is
about values and not expressions, so that

v = java.lang.Math.random();


Well, most often it is about expressions:

a = 2;
b = 1;
v = a * a + b;
System.out.println( v == 5 );

Had darn well better print 'true';

Math.random() is kind of an exception, as well as NaN, which has its own
semantics for comparisons.

It's fair to point out that objects have states, and method invocation
often returns different values based on their internal state.

InputStream in = ...
v = in.read();

Is going to return a different value for each invocation, generally
speaking.

We're getting into the difference between traditional languages, which
do have state, and functional languages, which try to avoid mutable
state whenever possible. Functional languages try to mimic the behavior
of algebra and mathematics, so that's why they look a lot closer the
mathematical formulas and properties you are used to from that field.

But Java isn't functional programming, and those properties you learned
for algebra aren't going to always work here. Thus, learning Java
involves learning a new set of rules, not trying to make Java work like
the other set of rules.
 
K

Kevin McMurtrie

I once read the »Assignment Principle«. It says that after
an assignment a comparison with the assigned value yields
true. Assuming v was declared properly:

v = 2;
java.lang.System.out.println( v == 2 ); // prints true

I think we can assume a single thread of execution and
normal memory [not I/O registers or so]. Also, it is
about values and not expressions, so that

v = java.lang.Math.random();
java.lang.System.out.println( v == java.lang.Math.random() );

is not a counterexample.

Being cautious, I'd like to ask: Do you see any exceptions,
where this does not hold? (I suggest to reply only if the
answer to that question is »yes«.)


NaN never matches anything, even itself. This trick is great for
attacking loops that exit on the condition of a floating point value.
System.out.println(0.0/0.0 == 0.0/0.0); //False
System.out.println(0f/0f == 0f/0f); //False
System.out.println(0d/0d < 0d); //False
System.out.println(0d/0d == 0d); //False
System.out.println(0d/0d > 0d); //False
System.out.println(0.0/0.0 != 0.0/0.0); //True



Bugs that look like violations:

- Implicit reduction and expansion of precision
int a= 1;
a+= 0.2;
System.out.println(a == 1 + 0.2); //False.
System.out.println(1/10f == 1/10.0); //False.
System.out.println(1/10f == 1/10); //False.
System.out.println(1/2f == 1/2.0); //True.


- Volatile fields may be changed immediately by other threads.

- If non-volatile shared memory is altered by another thread, it may or
may not appear to be different when tested. Whether or not it can be
different depends on register caching and entering safe points, and
those conditions may change as HotSpot alters optimization.

- There can be JVM bugs too. There have been cases in the past where
swapping two non-null static object references having no other
references during a GC would result in one reference becoming null.
There have been bugs in loop unrolling and native instruction order
optimizations that lead to corrupted values.
 
R

Robert Klemme

Math.random() is kind of an exception, as well as NaN, which has its own
semantics for comparisons.

It's fair to point out that objects have states, and method invocation
often returns different values based on their internal state.

InputStream in = ...
v = in.read();

Is going to return a different value for each invocation, generally
speaking.

That's why I would disagree calling Math.random() an exception. So
basically the original quoted principle can only reasonably apply to
values (object references and primitive type values). And there NaN is
really an exception.

Kind regards

robert
 
F

FredK

Well, most often it is about expressions:



a = 2;

b = 1;

v = a * a + b;

System.out.println( v == 5 );



Had darn well better print 'true';

I don't think this fits the definition. "5" is not the assigned value.
The test should be
v == (a * a + b)

Consider
double a = 2.3;
double b = 1.1;
double c = a + b;

Then the test
c == 3.4
may or may not be true.
However, the test
c == (a+b)
should be true.

--
Fred K



(snip)
 
M

markspace

That's why I would disagree calling Math.random() an exception. So
basically the original quoted principle can only reasonably apply to
values (object references and primitive type values). And there NaN is
really an exception.

Too many exceptions mean that the rule is wrong, imo. I'm going to
stick with "non-functional languages have their own set of rules" and
not try to shoe-horn Java into a functional mindset and end up with a
bunch of exceptions to each and every rule of functional programming.
 
R

Robert Klemme

Too many exceptions mean that the rule is wrong, imo. I'm going to
stick with "non-functional languages have their own set of rules" and
not try to shoe-horn Java into a functional mindset and end up with a
bunch of exceptions to each and every rule of functional programming.

I was not under the impression that someone wanted to force a functional mindset into Java. I took the "assignment principle just for what was posted.. All I am saying is that if one holds this up it cannot be claimed for arbitrary expressions but really only values on the right hand side (primitive type values or references). That would not make Math.random() one of a few exceptions but _all_ expressions involving method calls. Maybe I just misread your comment to restrict exception to Math.random().

Kind regards

robert
 
J

Jussi Piitulainen

Robert said:
I was not under the impression that someone wanted to force a
functional mindset into Java. I took the "assignment principle just
for what was posted. All I am saying is that if one holds this up
it cannot be claimed for arbitrary expressions but really only
values on the right hand side (primitive type values or references).
That would not make Math.random() one of a few exceptions but _all_
expressions involving method calls. Maybe I just misread your
comment to restrict exception to Math.random().

I'm not quite used to assignment statements in functional programming,
but I think I did learn this rule in terms of expressions: after an
assignment, the value of the variable is the value of the expression
*with the previous value of the variable substituted to the variable
itself*. There may have been an auxiliary variable to hold the value -
probably there was.

// v == v0
v = f(v);
// v == f(v0)

Probably v != f(v0) at this point. Certainly even after c = c + 1; it
is the case that c != c + 1.

This does assume that expressions, including function calls, don't
have side effects that affect their value.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top