In this section we'll discuss simple local assignment to variables, multiple local assignment, and installation and use of method functions. See also the operator =, which handles other forms of assignment, as well as the operator <-, which is an assignment operator that evaluates its left hand side and can have assignment methods installed for it by the user.
simple local assignment
-
- Inputs:
- Consequences:
- a new local variable x is created. The scope of x is the current function body, or if there is none, the current file
- e is assigned to x, so future references to the value of x yield e
- a warning message is issued if a local variable with the same name has already been created
- Outputs:
- a thing, the value of the expression is e
i1 : x
o1 = x
o1 : Symbol
|
i2 : x := 4
o2 = 4
|
i3 : x
o3 = 4
|
In the next example, we see that the scope of the local variable p is limited to the body of the function.
i4 : g = () -> ( p := 444; p )
o4 = g
o4 : FunctionClosure
|
i5 : g()
o5 = 444
|
i6 : p
o6 = p
o6 : Symbol
|
In this example, we see that a function returned by another function retains access to the values of local variables in its scope.
i7 : g = () -> ( p := 444; () -> p )
--warning: g redefined
o7 = g
o7 : FunctionClosure
|
i8 : g()
o8 = --Function[stdio:7:25-7:28]--
o8 : FunctionClosure
|
i9 : oo ()
o9 = 444
|
Functions returned by a function can also modify local variables within their scope, thereby communicating with each other.
i10 : g = () -> ( p := 444; (() -> p, i -> p = i))
--warning: g redefined
o10 = g
o10 : FunctionClosure
|
i11 : (b,c) = g()
o11 = (b, c)
o11 : Sequence
|
i12 : b()
o12 = 444
|
i13 : c 555
o13 = 555
|
i14 : b()
o14 = 555
|
Since the value of the entire expression is e, and since the operator = is right-associative (see precedence of operators), e can be easily assigned to more than one variable, as in the following example.
i15 : a := b := 44
o15 = 44
|
i16 : a
o16 = 44
|
i17 : b
o17 = 44
|
multiple local assignment
- Usage:
(x,y,z,...) := (c,d,e,...)
- Inputs:
- Consequences:
- new local variables x, y, z, ... are created
- the expressions c,d,e,... are assigned to the variables x,y,z,..., respectively, as above.
- If the left hand side has more elements than the right hand side, then the extra symbols on the left side are given the value null.
- If the left hand side has fewer elements than the right hand side, then the last symbol on the left hand side is given as value a sequence containing the trailing elements of the right hand side.
- If the right hand side is not a sequence, then it is assigned to the first symbol on the left, and the remaining symbols are assigned the value null.
- Outputs:
- the value of the expression is (c,d,e,...)
Multiple assignment effectively means that functions can return multiple values usefully.
i18 : f = i -> (i,i^2)
o18 = f
o18 : FunctionClosure
|
i19 : (r,s) := f 9
o19 = (9, 81)
o19 : Sequence
|
i20 : r
o20 = 9
|
i21 : s
o21 = 81
|
installing methods for binary operators
- Usage:
X OP Y := (x,y) -> ...
- Inputs:
- Consequences:
- the function on the right hand side is installed as the method for X OP Y. See the next subsection below for using it.
- Outputs:
- the value of the expression is the same as the function on the right hand side
The first line of the following example illustrates the syntax above.
i22 : String * String := peek;
|
i23 : "left" * "right"
o23 = ("left", "right")
|
Warning: the installation of new methods may supplant old ones, changing the behavior of Macaulay 2.
using methods for binary operators
-
- Inputs:
- x, an object of type X
- OP, one of the binary operators for which users may install methods, listed above. The operator SPACE, indicating adjacency, may be omitted from the usage above.
- y, an object of type Y
- Outputs:
- the previously installed method for X OP Y is called with arguments (x,y), and its return value is returned. If no such method has been installed, then Macaulay 2 searches for a method for X' OP Y', where X' is an ancestor of X and Y' is an ancestor of Y (see inheritance for details).
The second line of the following example illustrates the syntax above.
i24 : String * Number := peek;
|
i25 : "left" * 33
o25 = ("left", 33)
|
i26 : "left" * 3.3
o26 = ("left", 3.3)
|
Some methods for operators are
internal, and cannot be successfully overridden by the user, as we illustrate in the next example, where we try (and fail) to override the definition of the sum of two integers.
i27 : ZZ + ZZ := (x,y) -> x+y+100
o27 = --Function[stdio:27:17-27:24]--
o27 : FunctionClosure
|
i28 : 3 + 4
o28 = 7
|
By contrast, addition of complex numbers is not internal, and can be overridden.
i29 : CC + CC := (w,z) -> w*z
o29 = --Function[stdio:29:17-29:22]--
o29 : FunctionClosure
|
i30 : ii + ii
o30 = - 1. + 0.ii
o30 : CC
|
installing methods for unary prefix operators
-
- Inputs:
- Consequences:
- the function on the right hand side is installed as the method for OP X. See the next subsection below for using it.
- Outputs:
- the value of the expression is the same as the function on the right hand side
The first line of the following example illustrates the syntax above.
i31 : - String := peek;
|
i32 : - "foo"
o32 = "foo"
|
Warning: the installation of new methods may supplant old ones, changing the behavior of Macaulay 2.
using methods for unary prefix operators
-
- Inputs:
- OP, one of the unary prefix operators for which users may install methods, listed above.
- x, an object of type X
- Outputs:
- the previously installed method for OP X is called with argument x, and its return value is returned. If no such method has been installed, then Macaulay 2 searches for a method for OP X', where X' is an ancestor of X (see inheritance for details).
The second line of the following example illustrates the syntax above.
i33 : - String := peek;
|
i34 : - "foo"
o34 = "foo"
|
installing methods for unary postfix operators
-
- Inputs:
- OP, one of the unary postfix operators for which users may install methods, namely: (*) ~
- X, a type
- (x) -> ..., a function
- Consequences:
- the function on the right hand side is installed as the method for OP X. See the next subsection below for using it.
- Outputs:
- the value of the expression is the same as the function on the right hand side
The first line of the following example illustrates the syntax above.
i35 : String ~ := peek;
|
i36 : "foo" ~
o36 = "foo"
|
Warning: the installation of new methods may supplant old ones, changing the behavior of Macaulay 2.
using methods for unary postfix operators
-
- Inputs:
- x, an object of type X
- OP, one of the unary postfix operators for which users may install methods, listed above.
- Outputs:
- the previously installed method for X OP is called with argument= x, and its return value is returned. If no such method has been installed, then Macaulay 2 searches for a method for to X' OP, where X' is an ancestor of X (see inheritance for details).
The second line of the following example illustrates the syntax above.
i37 : String ~ := peek;
|
i38 : "foo" ~
o38 = "foo"
|
installing unary methods for method functions
- Usage:
f X := (x) -> ...
f(X) := (x) -> ...
- Inputs:
- f, a previously defined method function. A method function may be created with the function method.
- X, a type
- (x) -> ..., a function
- Consequences:
- the function on the right hand side is installed as the method for assignment to f X. See the next subsection below for using it.
The first line of the following example illustrates the syntax above, using
source, which happens to be a method function.
i39 : source String := peek;
|
i40 : source "foo"
o40 = "foo"
|
Warning: the installation of new methods may supplant old ones, changing the behavior of Macaulay 2.
using unary methods for method functions
-
- Inputs:
- f, a method function
- x, an object of type X
- Outputs:
- the previously installed method for f X is called with argument x, and its return value is returned
The second line of the following example illustrates the syntax above, using
source, which happens to be a method function.
i41 : source String := peek;
|
i42 : source "foo"
o42 = "foo"
|
installing binary methods for method functions
- Usage:
f(X,Y) := (x,y) -> ...
- Inputs:
- f, a previously defined method function. A method function may be created with the function method.
- X, a type
- Y, a type
- (x,y) -> ..., a function
- Consequences:
- the function on the right hand side is installed as the method for f(X,Y). See the next subsection below for using it.
The first line of the following example illustrates the syntax above, using
source, which happens to be a method function.
i43 : source(String,Number) := peek;
|
i44 : source("foo",33)
o44 = ("foo", 33)
|
i45 : source("foo",3.3)
o45 = ("foo", 3.3)
|
Warning: the installation of new methods may supplant old ones, changing the behavior of Macaulay 2.
The same syntax works for 3 or 4 arguments.
using binary methods for method functions
-
- Inputs:
- f, a method function
- x, an object of type X
- y, an object of type Y
- Outputs:
- the previously installed method for f(X,Y) is called with arguments (x,y), and the return value is returned. If no such method has been installed, then Macaulay 2 searches for a method for f(X',Y'), where X' is an ancestor of X and Y' is an ancestor of Y (see inheritance for details).
The second line of the following example illustrates the syntax above, using
source, which happens to be a method function.
i46 : source(String,String) := peek;
|
i47 : source("foo","bar")
o47 = ("foo", "bar")
|
The same syntax works for 3 or 4 arguments.
Another use of the operator := is for installing methods for creation of new objects. For details, see new.