Chapter 14

The Built-In Macros and Special Definitions

Function Macros

Function macros provide syntax for assignment and for conditional execution. These three built-in function macros may be called using function-call syntax or operator syntax.

Table 14-4 Function Macros

Macro

Description

Page

:=

Stores a new value in a location.

409

|

Returns the value of the first of two operands that is true.

412

&

If the value of a first operand is true, executes a second operand and returns its values.

412

Assignment

:= [Function Macro]


Stores a new value in a location.

Macro Call:

place := new-value

Arguments:
place

expressionbnf

new-value

expressionbnf

Values:

new-value, an instance of <object>.

Description:

:= stores new-value in place and returns new-value.

place may be a variable, a getter function or macro call with a corresponding setter, a slot access, or an element reference.

new-value may be any operand. It is executed, and its value is stored in place.

In all cases, new-value must be an appropriate type for place or an error is signaled.

The new-value of an assignment statement is executed first, followed by the place (assuming the place requires any execution, which will only be true if it is not a binding name).

Assignment to a binding

If place is a binding name, then new-value is stored in the binding. It is an error if there is no binding corresponding to place. (:= cannot be used to create bindings, only to change their values.) An error is also signaled if place is a binding specialized to a type and the new-value is not of that type.

define variable *number* = 10;
*number*
  10
*number* := *number* + 10;
  20
*number*
  20 
Assignment to a function or function macro

If place has the syntax of a function call, then := will invoke the corresponding setter function. Given a binding named fun, the corresponding setter is the binding named fun-setter in the current environment.

:= maps place to place-setter without regard for whether place is a function or a macro. It does not expand a macro call on the left-hand side before determining the setter.

With the exception of the order of execution and a guaranteed return value, the following three expressions are equivalent:

*top-view*.subviews := generate-subviews()
subviews(*top-view*) := generate-subviews()
subviews-setter(generate-subviews(), *top-view*) 

(The differences are as follows: the execution time of subviews-setter is undefined in the first two expressions but defined in the last; the first two expressions will return the value of the call to generate-subviews while the last will return the value of the call to subviews-setter.)

name(arg1,…argn ) := new-value 

behaves exactly the same as

begin
  let temp = new-value;
  name-setter(temp, arg1,…argn );
  temp
end

This is true regardless of whether name and name-setter are functions or macros. Here temp stands for a variable with a unique name. If name-setter is a macro, it is responsible for the order of execution of arg1,…argn.

The same considerations apply to arg.name := new-value.

Assignment to element references

Just as [] can be used as syntax for element and aref, [] and := can be used as syntax for element-setter and aref-setter. For example, the following three expressions are equivalent:

foo[2] := "quux"
element (foo, 2) := "quux"
element-setter ("quux", foo, 2). 

Conditional Execution

| [Function Macro]


Returns the value of the first of two operands that is true.

Macro Call:

one | another

Arguments:
one

expressionbnf

another

expressionbnf

Values:

Zero or more instances of <object>.

Description:

| (logical or) executes one. If the first value of one is true, that value is returned and another is not executed. Otherwise another is executed and its values are returned.

& [Function Macro]


If the value of a first operand is true, executes a second operand and returns its values.

Macro Call:

one & anothervalues

Arguments:
one

expressionbnf

another

expressionbnf

Values:

Zero or more instances of <object>.

Description:

& (logical and) executes one. If the first value returned by one is false, #f is returned and another is not executed. Otherwise, another is executed and its values are returned.