diff doc/interpreter/expr.txi @ 3294:bfe1573bd2ae

[project @ 1999-10-19 10:06:07 by jwe]
author jwe
date Tue, 19 Oct 1999 10:08:42 +0000 (1999-10-19)
parents
children 86873384cd10
line wrap: on
line diff
new file mode 100644
--- /dev/null
+++ b/doc/interpreter/expr.txi
@@ -0,0 +1,1131 @@
+@c Copyright (C) 1996, 1997 John W. Eaton
+@c This is part of the Octave manual.
+@c For copying conditions, see the file gpl.texi.
+
+@node Expressions, Evaluation, Variables, Top
+@chapter Expressions
+@cindex expressions
+
+Expressions are the basic building block of statements in Octave.  An
+expression evaluates to a value, which you can print, test, store in a
+variable, pass to a function, or assign a new value to a variable with
+an assignment operator.
+
+An expression can serve as a statement on its own.  Most other kinds of
+statements contain one or more expressions which specify data to be
+operated on.  As in other languages, expressions in Octave include
+variables, array references, constants, and function calls, as well as
+combinations of these with various operators.
+
+@menu
+* Index Expressions::           
+* Calling Functions::           
+* Arithmetic Ops::              
+* Comparison Ops::              
+* Boolean Expressions::         
+* Assignment Ops::              
+* Increment Ops::               
+* Operator Precedence::         
+@end menu
+
+@node Index Expressions, Calling Functions, Expressions, Expressions
+@section Index Expressions
+
+@opindex (
+@opindex )
+
+An @dfn{index expression} allows you to reference or extract selected
+elements of a matrix or vector.
+
+Indices may be scalars, vectors, ranges, or the special operator
+@samp{:}, which may be used to select entire rows or columns.
+
+Vectors are indexed using a single expression.  Matrices require two
+indices unless the value of the built-in variable
+@code{do_fortran_indexing} is nonzero, in which case matrices may
+also be indexed by a single expression.
+
+@defvr {Built-in Variable} do_fortran_indexing
+If the value of @code{do_fortran_indexing} is nonzero, Octave allows 
+you to select elements of a two-dimensional matrix using a single index
+by treating the matrix as a single vector created from the columns of
+the matrix.  The default value is 0. 
+@end defvr
+
+Given the matrix
+
+@example
+a = [1, 2; 3, 4]
+@end example
+
+@noindent
+all of the following expressions are equivalent
+
+@example
+@group
+a (1, [1, 2])
+a (1, 1:2)
+a (1, :)
+@end group
+@end example
+
+@noindent
+and select the first row of the matrix.
+
+A special form of indexing may be used to select elements of a matrix or
+vector.  If the indices are vectors made up of only ones and zeros, the
+result is a new matrix whose elements correspond to the elements of the
+index vector that are equal to one.  For example,
+
+@example
+@group
+a = [1, 2; 3, 4];
+a ([1, 0], :)
+@end group
+@end example
+
+@noindent
+selects the first row of the matrix @code{a}.
+
+This operation can be useful for selecting elements of a matrix based on
+some condition, since the comparison operators return matrices of ones
+and zeros.
+
+This special zero-one form of indexing leads to a conflict with the
+standard indexing operation.  For example, should the following
+statements
+
+@example
+@group
+a = [1, 2; 3, 4];
+a ([1, 1], :)
+@end group
+@end example
+
+@noindent
+return the original matrix, or the matrix formed by selecting the first
+row twice?  Although this conflict is not likely to arise very often in
+practice, you may select the behavior you prefer by setting the built-in
+variable @code{prefer_zero_one_indexing}.
+
+@defvr {Built-in Variable} prefer_zero_one_indexing
+If the value of @code{prefer_zero_one_indexing} is nonzero, Octave
+will perform zero-one style indexing when there is a conflict with the
+normal indexing rules.  @xref{Index Expressions}.  For example, given a
+matrix
+
+@example
+a = [1, 2, 3, 4]
+@end example
+
+@noindent
+with @code{prefer_zero_one_indexing} is set to nonzero, the
+expression
+
+@example
+a ([1, 1, 1, 1])
+@end example
+
+@noindent
+results in the matrix @code{[ 1, 2, 3, 4 ]}.  If the value of
+@code{prefer_zero_one_indexing} set to 0, the result would be
+the matrix @code{[ 1, 1, 1, 1 ]}.
+
+In the first case, Octave is selecting each element corresponding to a
+@samp{1} in the index vector.  In the second, Octave is selecting the
+first element multiple times.
+
+The default value for @code{prefer_zero_one_indexing} is 0.
+@end defvr
+
+Finally, indexing a scalar with a vector of ones can be used to create a
+vector the same size as the index vector, with each element equal to
+the value of the original scalar.  For example, the following statements
+
+@example
+@group
+a = 13;
+a ([1, 1, 1, 1])
+@end group
+@end example
+
+@noindent
+produce a vector whose four elements are all equal to 13.
+
+Similarly, indexing a scalar with two vectors of ones can be used to
+create a matrix.  For example the following statements
+
+@example
+@group
+a = 13;
+a ([1, 1], [1, 1, 1])
+@end group
+@end example
+
+@noindent
+create a 2 by 3 matrix with all elements equal to 13.
+
+This is an obscure notation and should be avoided.  It is better to
+use the function @code{ones} to generate a matrix of the appropriate
+size whose elements are all one, and then to scale it to produce the
+desired result.  @xref{Special Utility Matrices}.
+
+@defvr {Built-in Variable} prefer_column_vectors
+If @code{prefer_column_vectors} is nonzero, operations like
+
+@example
+for i = 1:10
+  a (i) = i;
+endfor
+@end example
+
+@noindent
+(for @code{a} previously  undefined) produce column vectors.  Otherwise, row
+vectors are preferred.  The default value is 1.
+
+If a variable is already defined to be a vector (a matrix with a single
+row or column), the original orientation is respected, regardless of the
+value of @code{prefer_column_vectors}.
+@end defvr
+
+@defvr {Built-in Variable} resize_on_range_error
+If the value of @code{resize_on_range_error} is nonzero, expressions
+like
+
+@example
+for i = 1:10
+  a (i) = sqrt (i);
+endfor
+@end example
+
+@noindent
+(for @code{a} previously undefined) result in the variable @code{a}
+being resized to be just large enough to hold the new value.  New
+elements that have not been given a value are set to zero.  If the value
+of @code{resize_on_range_error} is 0, an error message is printed and
+control is returned to the top level.  The default value is 1.
+@end defvr
+
+Note that it is quite inefficient to create a vector using a loop like
+the one shown in the example above.  In this particular case, it would
+have been much more efficient to use the expression
+
+@example
+a = sqrt (1:10);
+@end example
+
+@noindent
+thus avoiding the loop entirely.  In cases where a loop is still
+required, or a number of values must be combined to form a larger
+matrix, it is generally much faster to set the size of the matrix first,
+and then insert elements using indexing commands.  For example, given a
+matrix @code{a},
+
+@example
+@group
+[nr, nc] = size (a);
+x = zeros (nr, n * nc);
+for i = 1:n
+  x(:,(i-1)*n+1:i*n) = a;
+endfor
+@end group
+@end example
+
+@noindent
+is considerably faster than
+
+@example
+@group
+x = a;
+for i = 1:n-1
+  x = [x, a];
+endfor
+@end group
+@end example
+
+@noindent
+particularly for large matrices because Octave does not have to
+repeatedly resize the result.
+
+@node Calling Functions, Arithmetic Ops, Index Expressions, Expressions
+@section Calling Functions
+
+A @dfn{function} is a name for a particular calculation.  Because it has
+a name, you can ask for it by name at any point in the program.  For
+example, the function @code{sqrt} computes the square root of a number.
+
+A fixed set of functions are @dfn{built-in}, which means they are
+available in every Octave program.  The @code{sqrt} function is one of
+these.  In addition, you can define your own functions.
+@xref{Functions and Scripts}, for information about how to do this.
+
+@cindex arguments in function call
+The way to use a function is with a @dfn{function call} expression,
+which consists of the function name followed by a list of
+@dfn{arguments} in parentheses. The arguments are expressions which give
+the raw materials for the calculation that the function will do.  When
+there is more than one argument, they are separated by commas.  If there
+are no arguments, you can omit the parentheses, but it is a good idea to
+include them anyway, to clearly indicate that a function call was
+intended.  Here are some examples:
+
+@example
+@group
+sqrt (x^2 + y^2)      # @r{One argument}
+ones (n, m)           # @r{Two arguments}
+rand ()               # @r{No arguments}
+@end group
+@end example
+
+Each function expects a particular number of arguments.  For example, the
+@code{sqrt} function must be called with a single argument, the number
+to take the square root of:
+
+@example
+sqrt (@var{argument})
+@end example
+
+Some of the built-in functions take a variable number of arguments,
+depending on the particular usage, and their behavior is different
+depending on the number of arguments supplied.
+
+Like every other expression, the function call has a value, which is
+computed by the function based on the arguments you give it.  In this
+example, the value of @code{sqrt (@var{argument})} is the square root of
+the argument.  A function can also have side effects, such as assigning
+the values of certain variables or doing input or output operations.
+
+Unlike most languages, functions in Octave may return multiple values.
+For example, the following statement
+
+@example
+[u, s, v] = svd (a)
+@end example
+
+@noindent
+computes the singular value decomposition of the matrix @code{a} and
+assigns the three result matrices to @code{u}, @code{s}, and @code{v}.
+
+The left side of a multiple assignment expression is itself a list of
+expressions, and is allowed to be a list of variable names or index
+expressions.  See also @ref{Index Expressions}, and @ref{Assignment Ops}.
+
+@menu
+* Call by Value::               
+* Recursion::                   
+@end menu
+
+@node Call by Value, Recursion, Calling Functions, Calling Functions
+@subsection Call by Value
+
+In Octave, unlike Fortran, function arguments are passed by value, which
+means that each argument in a function call is evaluated and assigned to
+a temporary location in memory before being passed to the function.
+There is currently no way to specify that a function parameter should be
+passed by reference instead of by value.  This means that it is
+impossible to directly alter the value of function parameter in the
+calling function.  It can only change the local copy within the function
+body.  For example, the function
+
+@example
+@group
+function f (x, n)
+  while (n-- > 0)
+    disp (x);
+  endwhile
+endfunction
+@end group
+@end example
+
+@noindent
+displays the value of the first argument @var{n} times.  In this
+function, the variable @var{n} is used as a temporary variable without
+having to worry that its value might also change in the calling
+function.  Call by value is also useful because it is always possible to
+pass constants for any function parameter without first having to
+determine that the function will not attempt to modify the parameter.
+
+The caller may use a variable as the expression for the argument, but
+the called function does not know this: it only knows what value the
+argument had.  For example, given a function called as
+
+@example
+@group
+foo = "bar";
+fcn (foo)
+@end group
+@end example
+
+@noindent
+you should not think of the argument as being ``the variable
+@code{foo}.''  Instead, think of the argument as the string value,
+@code{"bar"}.
+
+Even though Octave uses pass-by-value semantics for function arguments,
+values are not copied unnecessarily.  For example,
+
+@example
+@group
+x = rand (1000);
+f (x);
+@end group
+@end example
+
+@noindent
+does not actually force two 1000 by 1000 element matrices to exist
+@emph{unless} the function @code{f} modifies the value of its
+argument.  Then Octave must create a copy to avoid changing the
+value outside the scope of the function @code{f}, or attempting (and
+probably failing!) to modify the value of a constant or the value of a
+temporary result.
+
+@node Recursion,  , Call by Value, Calling Functions
+@subsection Recursion
+@cindex factorial function
+
+With some restrictions@footnote{Some of Octave's function are
+implemented in terms of functions that cannot be called recursively.
+For example, the ODE solver @code{lsode} is ultimately implemented in a
+Fortran subroutine that cannot be called recursively, so @code{lsode}
+should not be called either directly or indirectly from within the
+user-supplied function that @code{lsode} requires.  Doing so will result
+in undefined behavior.}, recursive function calls are allowed.  A
+@dfn{recursive function} is one which calls itself, either directly or
+indirectly.  For example, here is an inefficient@footnote{It would be
+much better to use @code{prod (1:n)}, or @code{gamma (n+1)} instead,
+after first checking to ensure that the value @code{n} is actually a
+positive integer.} way to compute the factorial of a given integer:
+
+@example
+@group
+function retval = fact (n)
+  if (n > 0)
+    retval = n * fact (n-1);
+  else
+    retval = 1;
+  endif
+endfunction
+@end group
+@end example
+
+This function is recursive because it calls itself directly.  It
+eventually terminates because each time it calls itself, it uses an
+argument that is one less than was used for the previous call.  Once the
+argument is no longer greater than zero, it does not call itself, and
+the recursion ends.
+
+The built-in variable @code{max_recursion_depth} specifies a limit to
+the recursion depth and prevents Octave from recursing infinitely.
+
+@defvr max_recursion_depth
+Limit the number of times a function may be called recursively.
+If the limit is exceeded, an error message is printed and control
+returns to the top level.
+
+The default value is 256.
+@end defvr
+
+@node Arithmetic Ops, Comparison Ops, Calling Functions, Expressions
+@section Arithmetic Operators
+@cindex arithmetic operators
+@cindex operators, arithmetic
+@cindex addition
+@cindex subtraction
+@cindex multiplication
+@cindex matrix multiplication
+@cindex division
+@cindex quotient
+@cindex negation
+@cindex unary minus
+@cindex exponentiation
+@cindex transpose
+@cindex Hermitian operator
+@cindex transpose, complex-conjugate
+@cindex complex-conjugate transpose
+
+The following arithmetic operators are available, and work on scalars
+and matrices.
+
+@table @code
+@item @var{x} + @var{y}
+@opindex +
+Addition.  If both operands are matrices, the number of rows and columns
+must both agree.  If one operand is a scalar, its value is added to
+all the elements of the other operand.
+
+@item @var{x} .+ @var{y}
+@opindex .+
+Element by element addition.  This operator is equivalent to @code{+}.
+
+@item @var{x} - @var{y}
+@opindex -
+Subtraction.  If both operands are matrices, the number of rows and
+columns of both must agree.
+
+@item @var{x} .- @var{y}
+Element by element subtraction.  This operator is equivalent to @code{-}.
+
+@item @var{x} * @var{y}
+@opindex *
+Matrix multiplication.  The number of columns of @var{x} must agree
+with the number of rows of @var{y}.
+
+@item @var{x} .* @var{y}
+@opindex .*
+Element by element multiplication.  If both operands are matrices, the
+number of rows and columns must both agree.
+
+@item @var{x} / @var{y}
+@opindex /
+Right division.  This is conceptually equivalent to the expression
+
+@example
+(inverse (y') * x')'
+@end example
+
+@noindent
+but it is computed without forming the inverse of @var{y'}.
+
+If the system is not square, or if the coefficient matrix is singular,
+a minimum norm solution is computed.
+
+@item @var{x} ./ @var{y}
+@opindex ./
+Element by element right division.
+
+@item @var{x} \ @var{y}
+@opindex \
+Left division.  This is conceptually equivalent to the expression
+
+@example
+inverse (x) * y
+@end example
+
+@noindent
+but it is computed without forming the inverse of @var{x}.
+
+If the system is not square, or if the coefficient matrix is singular,
+a minimum norm solution is computed.
+
+@item @var{x} .\ @var{y}
+@opindex .\
+Element by element left division.  Each element of @var{y} is divided
+by each corresponding element of @var{x}.
+
+@item @var{x} ^ @var{y}
+@itemx @var{x} ** @var{y}
+@opindex **
+@opindex ^
+Power operator.  If @var{x} and @var{y} are both scalars, this operator
+returns @var{x} raised to the power @var{y}.  If @var{x} is a scalar and
+@var{y} is a square matrix, the result is computed using an eigenvalue
+expansion.  If @var{x} is a square matrix. the result is computed by
+repeated multiplication if @var{y} is an integer, and by an eigenvalue
+expansion if @var{y} is not an integer.  An error results if both
+@var{x} and @var{y} are matrices.
+
+The implementation of this operator needs to be improved.
+
+@item @var{x} .^ @var{y}
+@item @var{x} .** @var{y}
+@opindex .**
+@opindex .^
+Element by element power operator.  If both operands are matrices, the
+number of rows and columns must both agree.
+
+@item -@var{x}
+@opindex -
+Negation.
+
+@item +@var{x}
+@opindex +
+Unary plus.  This operator has no effect on the operand.
+
+@item @var{x}'
+@opindex '
+Complex conjugate transpose.  For real arguments, this operator is the
+same as the transpose operator.  For complex arguments, this operator is
+equivalent to the expression
+
+@example
+conj (x.')
+@end example
+
+@item @var{x}.'
+@opindex .'
+Transpose.
+@end table
+
+Note that because Octave's element by element operators begin with a
+@samp{.}, there is a possible ambiguity for statements like
+
+@example
+1./m
+@end example
+
+@noindent
+because the period could be interpreted either as part of the constant
+or as part of the operator.  To resolve this conflict, Octave treats the
+expression as if you had typed
+
+@example
+(1) ./ m
+@end example
+
+@noindent
+and not
+
+@example
+(1.) / m
+@end example
+
+@noindent
+Although this is inconsistent with the normal behavior of Octave's
+lexer, which usually prefers to break the input into tokens by
+preferring the longest possible match at any given point, it is more
+useful in this case.
+
+@defvr {Built-in Variable} warn_divide_by_zero
+If the value of @code{warn_divide_by_zero} is nonzero, a warning
+is issued when Octave encounters a division by zero.  If the value is
+0, the warning is omitted.  The default value is 1.
+@end defvr
+
+@node Comparison Ops, Boolean Expressions, Arithmetic Ops, Expressions
+@section Comparison Operators
+@cindex comparison expressions
+@cindex expressions, comparison
+@cindex relational operators
+@cindex operators, relational
+@cindex less than operator
+@cindex greater than operator
+@cindex equality operator
+@cindex tests for equality
+@cindex equality, tests for
+
+@dfn{Comparison operators} compare numeric values for relationships
+such as equality.  They are written using
+@emph{relational operators}.
+
+All of Octave's comparison operators return a value of 1 if the
+comparison is true, or 0 if it is false.  For matrix values, they all
+work on an element-by-element basis.  For example,
+
+@example
+@group
+[1, 2; 3, 4] == [1, 3; 2, 4]
+     @result{}  1  0
+         0  1
+@end group
+@end example
+
+If one operand is a scalar and the other is a matrix, the scalar is
+compared to each element of the matrix in turn, and the result is the
+same size as the matrix.
+
+@table @code
+@item @var{x} < @var{y}
+@opindex <
+True if @var{x} is less than @var{y}.
+
+@item @var{x} <= @var{y}
+@opindex <=
+True if @var{x} is less than or equal to @var{y}.
+
+@item @var{x} == @var{y}
+@opindex ==
+True if @var{x} is equal to @var{y}.
+
+@item @var{x} >= @var{y}
+@opindex >=
+True if @var{x} is greater than or equal to @var{y}.
+
+@item @var{x} > @var{y}
+@opindex >
+True if @var{x} is greater than @var{y}.
+
+@item @var{x} != @var{y}
+@itemx @var{x} ~= @var{y}
+@itemx @var{x} <> @var{y}
+@opindex !=
+@opindex ~=
+@opindex <>
+True if @var{x} is not equal to @var{y}.
+@end table
+
+String comparisons may also be performed with the @code{strcmp}
+function, not with the comparison operators listed above.
+@xref{Strings}.
+
+@node Boolean Expressions, Assignment Ops, Comparison Ops, Expressions
+@section Boolean Expressions
+@cindex expressions, boolean
+@cindex boolean expressions
+@cindex expressions, logical
+@cindex logical expressions
+@cindex operators, boolean
+@cindex boolean operators
+@cindex logical operators
+@cindex operators, logical
+@cindex and operator
+@cindex or operator
+@cindex not operator
+
+@menu
+* Element-by-element Boolean Operators::  
+* Short-circuit Boolean Operators::  
+@end menu
+
+@node Element-by-element Boolean Operators, Short-circuit Boolean Operators, Boolean Expressions, Boolean Expressions
+@subsection Element-by-element Boolean Operators
+@cindex element-by-element evaluation
+
+An @dfn{element-by-element boolean expression} is a combination of
+comparison expressions using the boolean
+operators ``or'' (@samp{|}), ``and'' (@samp{&}), and ``not'' (@samp{!}),
+along with parentheses to control nesting.  The truth of the boolean
+expression is computed by combining the truth values of the
+corresponding elements of the component expressions.  A value is
+considered to be false if it is zero, and true otherwise.
+
+Element-by-element boolean expressions can be used wherever comparison
+expressions can be used.  They can be used in @code{if} and @code{while}
+statements.  However, if a matrix value used as the condition in an
+@code{if} or @code{while} statement is only true if @emph{all} of its
+elements are nonzero.
+
+Like comparison operations, each element of an element-by-element
+boolean expression also has a numeric value (1 if true, 0 if false) that
+comes into play if the result of the boolean expression is stored in a
+variable, or used in arithmetic.
+
+Here are descriptions of the three element-by-element boolean operators.
+
+@table @code
+@item @var{boolean1} & @var{boolean2}
+@opindex &
+Elements of the result are true if both corresponding elements of
+@var{boolean1} and @var{boolean2} are true.
+
+@item @var{boolean1} | @var{boolean2}
+@opindex |
+Elements of the result are true if either of the corresponding elements
+of @var{boolean1} or @var{boolean2} is true.
+
+@item ! @var{boolean}
+@itemx ~ @var{boolean}
+@opindex ~
+@opindex !
+Each element of the result is true if the corresponding element of
+@var{boolean} is false.
+@end table
+
+For matrix operands, these operators work on an element-by-element
+basis.  For example, the expression
+
+@example
+[1, 0; 0, 1] & [1, 0; 2, 3]
+@end example
+
+@noindent
+returns a two by two identity matrix.
+
+For the binary operators, the dimensions of the operands must conform if
+both are matrices.  If one of the operands is a scalar and the other a
+matrix, the operator is applied to the scalar and each element of the
+matrix.
+
+For the binary element-by-element boolean operators, both subexpressions
+@var{boolean1} and @var{boolean2} are evaluated before computing the
+result.  This can make a difference when the expressions have side
+effects.  For example, in the expression
+
+@example
+a & b++
+@end example
+
+@noindent
+the value of the variable @var{b} is incremented even if the variable
+@var{a} is zero.
+
+This behavior is necessary for the boolean operators to work as
+described for matrix-valued operands.
+
+@node Short-circuit Boolean Operators,  , Element-by-element Boolean Operators, Boolean Expressions
+@subsection Short-circuit Boolean Operators
+@cindex short-circuit evaluation
+
+Combined with the implicit conversion to scalar values in @code{if} and
+@code{while} conditions, Octave's element-by-element boolean operators
+are often sufficient for performing most logical operations.  However,
+it is sometimes desirable to stop evaluating a boolean expression as
+soon as the overall truth value can be determined.  Octave's
+@dfn{short-circuit} boolean operators work this way.
+
+@table @code
+@item @var{boolean1} && @var{boolean2}
+@opindex &&
+The expression @var{boolean1} is evaluated and converted to a scalar
+using the equivalent of the operation @code{all (all (@var{boolean1}))}.
+If it is false, the result of the overall expression is 0.  If it is
+true, the expression @var{boolean2} is evaluated and converted to a
+scalar using the equivalent of the operation @code{all (all
+(@var{boolean1}))}.  If it is true, the result of the overall expression
+is 1.  Otherwise, the result of the overall expression is 0.
+
+@item @var{boolean1} || @var{boolean2}
+@opindex ||
+The expression @var{boolean1} is evaluated and converted to a scalar
+using the equivalent of the operation @code{all (all (@var{boolean1}))}.
+If it is true, the result of the overall expression is 1.  If it is
+false, the expression @var{boolean2} is evaluated and converted to a
+scalar using the equivalent of the operation @code{all (all
+(@var{boolean1}))}.  If it is true, the result of the overall expression
+is 1.  Otherwise, the result of the overall expression is 0.
+@end table
+
+The fact that both operands may not be evaluated before determining the
+overall truth value of the expression can be important.  For example, in
+the expression
+
+@example
+a && b++
+@end example
+
+@noindent
+the value of the variable @var{b} is only incremented if the variable
+@var{a} is nonzero.
+
+This can be used to write somewhat more concise code.  For example, it
+is possible write
+
+@example
+@group
+function f (a, b, c)
+  if (nargin > 2 && isstr (c))
+    @dots{}
+@end group
+@end example
+
+@noindent
+instead of having to use two @code{if} statements to avoid attempting to
+evaluate an argument that doesn't exist.  For example, without the
+short-circuit feature, it would be necessary to write
+
+@example
+@group
+function f (a, b, c)
+  if (nargin > 2)
+    if (isstr (c))
+      @dots{}
+@end group
+@end example
+
+Writing
+
+@example
+@group
+function f (a, b, c)
+  if (nargin > 2 & isstr (c))
+    @dots{}
+@end group
+@end example
+
+@noindent
+would result in an error if @code{f} were called with one or two
+arguments because Octave would be forced to try to evaluate both of the
+operands for the operator @samp{&}.
+
+@node Assignment Ops, Increment Ops, Boolean Expressions, Expressions
+@section Assignment Expressions
+@cindex assignment expressions
+@cindex assignment operators
+@cindex operators, assignment
+@cindex expressions, assignment
+
+@opindex =
+
+An @dfn{assignment} is an expression that stores a new value into a
+variable.  For example, the following expression assigns the value 1 to
+the variable @code{z}:
+
+@example
+z = 1
+@end example
+
+After this expression is executed, the variable @code{z} has the value 1.
+Whatever old value @code{z} had before the assignment is forgotten.
+The @samp{=} sign is called an @dfn{assignment operator}.
+
+Assignments can store string values also.  For example, the following
+expression would store the value @code{"this food is good"} in the
+variable @code{message}:
+
+@example
+@group
+thing = "food"
+predicate = "good"
+message = [ "this " , thing , " is " , predicate ]
+@end group
+@end example
+
+@noindent
+(This also illustrates concatenation of strings.)
+
+@cindex side effect
+Most operators (addition, concatenation, and so on) have no effect
+except to compute a value.  If you ignore the value, you might as well
+not use the operator.  An assignment operator is different.  It does
+produce a value, but even if you ignore the value, the assignment still
+makes itself felt through the alteration of the variable.  We call this
+a @dfn{side effect}.
+
+@cindex lvalue
+The left-hand operand of an assignment need not be a variable
+(@pxref{Variables}).  It can also be an element of a matrix
+(@pxref{Index Expressions}) or a list of return values
+(@pxref{Calling Functions}).  These are all called @dfn{lvalues}, which
+means they can appear on the left-hand side of an assignment operator.
+The right-hand operand may be any expression.  It produces the new value
+which the assignment stores in the specified variable, matrix element,
+or list of return values.
+
+It is important to note that variables do @emph{not} have permanent types.
+The type of a variable is simply the type of whatever value it happens
+to hold at the moment.  In the following program fragment, the variable
+@code{foo} has a numeric value at first, and a string value later on:
+
+@example
+@group
+octave:13> foo = 1
+foo = 1
+octave:13> foo = "bar"
+foo = bar
+@end group
+@end example
+
+@noindent
+When the second assignment gives @code{foo} a string value, the fact that
+it previously had a numeric value is forgotten.
+
+Assignment of a scalar to an indexed matrix sets all of the elements
+that are referenced by the indices to the scalar value.  For example, if
+@code{a} is a matrix with at least two columns,
+
+@example
+@group
+a(:, 2) = 5
+@end group
+@end example
+
+@noindent
+sets all the elements in the second column of @code{a} to 5.
+
+Assigning an empty matrix @samp{[]} works in most cases to allow you to
+delete rows or columns of matrices and vectors.  @xref{Empty Matrices}.
+For example, given a 4 by 5 matrix @var{A}, the assignment
+
+@example
+A (3, :) = []
+@end example
+
+@noindent
+deletes the third row of @var{A}, and the assignment
+
+@example
+A (:, 1:2:5) = []
+@end example
+
+@noindent
+deletes the first, third, and fifth columns.
+
+An assignment is an expression, so it has a value.  Thus, @code{z = 1}
+as an expression has the value 1.  One consequence of this is that you
+can write multiple assignments together:
+
+@example
+x = y = z = 0
+@end example
+
+@noindent
+stores the value 0 in all three variables.  It does this because the
+value of @code{z = 0}, which is 0, is stored into @code{y}, and then
+the value of @code{y = z = 0}, which is 0, is stored into @code{x}.
+
+This is also true of assignments to lists of values, so the following is
+a valid expression
+
+@example
+[a, b, c] = [u, s, v] = svd (a)
+@end example
+
+@noindent
+that is exactly equivalent to
+
+@example
+@group
+[u, s, v] = svd (a)
+a = u
+b = s
+c = v
+@end group
+@end example
+
+In expressions like this, the number of values in each part of the
+expression need not match.  For example, the expression
+
+@example
+[a, b, c, d] = [u, s, v] = svd (a)
+@end example
+
+@noindent
+is equivalent to the expression above, except that the value of the
+variable @samp{d} is left unchanged, and the expression
+
+@example
+[a, b] = [u, s, v] = svd (a)
+@end example
+
+@noindent
+is equivalent to 
+
+@example
+@group
+[u, s, v] = svd (a)
+a = u
+b = s
+@end group
+@end example
+
+You can use an assignment anywhere an expression is called for.  For
+example, it is valid to write @code{x != (y = 1)} to set @code{y} to 1
+and then test whether @code{x} equals 1.  But this style tends to make
+programs hard to read.  Except in a one-shot program, you should rewrite
+it to get rid of such nesting of assignments.  This is never very hard.
+
+@cindex increment operator
+@cindex decrement operator
+@cindex operators, increment
+@cindex operators, decrement
+
+@node Increment Ops, Operator Precedence, Assignment Ops, Expressions
+@section Increment Operators
+
+@emph{Increment operators} increase or decrease the value of a variable
+by 1.  The operator to increment a variable is written as @samp{++}.  It
+may be used to increment a variable either before or after taking its
+value.
+
+For example, to pre-increment the variable @var{x}, you would write
+@code{++@var{x}}.  This would add one to @var{x} and then return the new
+value of @var{x} as the result of the expression.  It is exactly the
+same as the expression @code{@var{x} = @var{x} + 1}.
+
+To post-increment a variable @var{x}, you would write @code{@var{x}++}.
+This adds one to the variable @var{x}, but returns the value that
+@var{x} had prior to incrementing it.  For example, if @var{x} is equal
+to 2, the result of the expression @code{@var{x}++} is 2, and the new
+value of @var{x} is 3.
+
+For matrix and vector arguments, the increment and decrement operators
+work on each element of the operand.
+
+Here is a list of all the increment and decrement expressions.
+
+@table @code
+@item ++@var{x}
+@opindex ++
+This expression increments the variable @var{x}.  The value of the
+expression is the @emph{new} value of @var{x}.  It is equivalent to the
+expression @code{@var{x} = @var{x} + 1}.
+
+@item --@var{x}
+@opindex @code{--}
+This expression decrements the variable @var{x}.  The value of the
+expression is the @emph{new} value of @var{x}.  It is equivalent to the
+expression @code{@var{x} = @var{x} - 1}.
+
+@item @var{x}++
+@opindex ++
+This expression causes the variable @var{x} to be incremented.  The
+value of the expression is the @emph{old} value of @var{x}.
+
+@item @var{x}--
+@opindex @code{--}
+This expression causes the variable @var{x} to be decremented.  The
+value of the expression is the @emph{old} value of @var{x}.
+@end table
+
+It is not currently possible to increment index expressions.  For
+example, you might expect that the expression @code{@var{v}(4)++} would
+increment the fourth element of the vector @var{v}, but instead it
+results in a parse error.  This problem may be fixed in a future
+release of Octave.
+
+@node Operator Precedence,  , Increment Ops, Expressions
+@section Operator Precedence
+@cindex operator precedence
+
+@dfn{Operator precedence} determines how operators are grouped, when
+different operators appear close by in one expression.  For example,
+@samp{*} has higher precedence than @samp{+}.  Thus, the expression
+@code{a + b * c} means to multiply @code{b} and @code{c}, and then add
+@code{a} to the product (i.e., @code{a + (b * c)}).
+
+You can overrule the precedence of the operators by using parentheses.
+You can think of the precedence rules as saying where the parentheses
+are assumed if you do not write parentheses yourself.  In fact, it is
+wise to use parentheses whenever you have an unusual combination of
+operators, because other people who read the program may not remember
+what the precedence is in this case.  You might forget as well, and then
+you too could make a mistake.  Explicit parentheses will help prevent
+any such mistake.
+
+When operators of equal precedence are used together, the leftmost
+operator groups first, except for the assignment and exponentiation
+operators, which group in the opposite order.  Thus, the expression
+@code{a - b + c} groups as @code{(a - b) + c}, but the expression
+@code{a = b = c} groups as @code{a = (b = c)}.
+
+The precedence of prefix unary operators is important when another
+operator follows the operand.  For example, @code{-x^2} means
+@code{-(x^2)}, because @samp{-} has lower precedence than @samp{^}.
+
+Here is a table of the operators in Octave, in order of increasing
+precedence.
+
+@table @code
+@item statement separators
+@samp{;}, @samp{,}.
+
+@item assignment
+@samp{=}.  This operator groups right to left.
+
+@item logical "or" and "and"
+@samp{||}, @samp{&&}.
+
+@item element-wise "or" and "and"
+@samp{|}, @samp{&}.
+
+@item relational
+@samp{<}, @samp{<=}, @samp{==}, @samp{>=}, @samp{>}, @samp{!=},
+@samp{~=}, @samp{<>}.
+
+@item colon
+@samp{:}.
+
+@item add, subtract
+@samp{+}, @samp{-}.
+
+@item multiply, divide
+@samp{*}, @samp{/}, @samp{\}, @samp{.\}, @samp{.*}, @samp{./}.
+
+@item transpose
+@samp{'}, @samp{.'}
+
+@item unary plus, minus, increment, decrement, and ``not''
+@samp{+}, @samp{-}, @samp{++}, @samp{--}, @samp{!}, @samp{~}.
+
+@item exponentiation
+@samp{^}, @samp{**}, @samp{.^}, @samp{.**}.
+@end table