In addition to supporting all the usual mathematical operations, in a manner analogous to that shown above for addition, APL defined other whole array operations necessary for a reasonably complete paradigm in which arrays are objects in their own right. These include reduction operations (e.g., +/A means sum all the elements of array A), construction operations (e.g., i4 constructs a vector of four elements whose values are 1,2,3,4), and inquiry operations (e.g., if B returns the shape of array B-a vector whose size is the rank of B and whose element values are the corresponding dimension sizes of B-then */B computes the total number of elements in array B). All such operations can be combined into more arbitrarily complex array-valued expressions (e.g., for a one-dimensional array Q, */Q + i*/Q is evaluated right to left (that's APL!) to generate a 1,2,3, vector the size of Q which is added to Q and the resulting elements multiplied together; if Q is the vector (3,2,4), then the value of */Q+i*/Q = */((3,2,4)+(1,2,3))=*/(4,4,7)=56). APL's introduction well before data parallelism became physically practical and when the processing of dynamic languages was inefficient, coupled with (what turned out to be) unpopular characteristics such as arcane notation and unnatural right-to-left evaluation, resulted in it not being used for many practical applications.