TITLE:: Operand
summary::Idempotent wrapper around math operations
categories:: Core
related:: Classes/AbstractFunction, Classes/Maybe, Classes/Ref, Classes/Rest

DESCRIPTION::
If you need to ensure that math operations always return the result wrapped in a specific object, you can use Operand or subclass from it.
For some practical examples, see its subclass link::Classes/Rest::. If you need to keep nested operations, use link::Classes/Maybe::.


Its creation is idempotent, that is code::Operand(Operand(x)) == Operand(x)::.


code::
// An Operand is an Operand is an Operand
Operand(Operand(Operand(1))) - 1 == 0
::

code::
// math operations
a = Operand(2);
b = Operand([1, 2, 3]);
c = a + b * a; // Operand([ 6, 8, 10 ])
c.value; // [ 6, 8, 10 ]
::

CLASSMETHODS::

METHOD:: new
argument:: value
Return a new instance of Operand, using an arbitrary object as value.

code::
a = Operand(1) + 7; // returns Operand(8)

// the *new method is idempotent:
Operand(Operand(Operand(1))) == Operator(1)
::


INSTANCEMETHODS::

PRIVATE:: composeBinaryOp, composeNAryOp, composeUnaryOp, performBinaryOpOnComplex, performBinaryOpOnSeqColl, performBinaryOpOnSignal, performBinaryOpOnSimpleNumber, reverseComposeBinaryOp

METHOD:: value
Set or return the current value.

code::
a = Operand(2) ** 8;
a.value; // 256
a.value = 78;
a.value; // 78
::

METHOD:: ==
argument:: obj
An Operand is equal to another one if their value are equal.
code::
Operand(1) == Operand(1);
Operand(1) + 2 == Operand(3);
::

METHOD:: hash
Two instances with the same value return the same hash value.
code::
Set[Operand(1), Operand(1)] == Set[Operand(1)] // true
::

METHOD:: dereferenceOperand
This method is called to avoid nesting. You may override it in subclasses to perform actions on resulting values.
code::Operand(Operand(1)) // Operand(1)::.



EXAMPLES::

code::
// you could make a class that always converts values to integers:

IntegerOperand : Operand {
	dereferenceOperand {
		^value.asInteger
	}
}

// then you would get:
IntegerOperand(1) + pi == IntegerOperand(4)
::



