# 2 Experimental Extensions

The extensions that remain experimental in Mozart 1.1.1 support the use of loops as expressions, i. e. loops that return a value. These extensions are supported by means of additional loop features.

## 2.1 While and Until

`while:E`

  expression `E` is checked on each iteration, just before entering the body of the loop. If it evaluates to `false`, we break out of the loop (see `break` feature).

`until:E`

  expression `E` is checked on each iteration, just after the body of the loop. If it evaluates to `true`, we break out of the loop.

Note that it is allowed to use both features in the same loop.

## 2.2 Find And Return a Value

The simplest way for a loop to return a value is to explicitly do so.

`return:R`

  binds `R` to a unary procedure. Invoking `{R E1}` immediately terminates the loop returning `E1` as its value.

`default:E2`

  if the loop terminates without the return procedure having been called, then `E2` is returned as the ``default'' value of the loop. Currently `E2` is evaluated before starting the loop, but this will hopefully change so that it is only evaluated on exit if necessary. If no default is specified and the return procedure is not invoked, then the loop raises an exception on termination

## 2.3 List Accumulator

A loop can be given a hidden accumulator in which a list is incrementally constructed and returned as the value of the loop when the latter terminates. This functionality is obtained by using one or more of the following loop features:

`collect:C`

  binds `C` to a unary procedure to accumulate elements of the list. Thus `{C E3}` adds `E3` as another element of the list. The value will appear in the list in chronological order of collection: the last one collected appears as last element of the list.

`append:A`

  binds `A` to a unary procedure to append a list of values to the accumulator.

`prepend:P`

  Similar, but for prepending to the accumulator.

Note that it is possible to use the features above in conjunction with `return`. Thus you can accumulate a list, but you can also return a different value e. g. in an exceptional situation.

## 2.4 Integer Accumulator

This functionality is even less official than for the list accumulator: we are not at all convinced that it is sufficiently frequently convenient to warrant special support. It is included simply because it was also in the Common Lisp loop macro which was one source of inspiration.

### 2.4.1 Computing an Extremum

One way to use an ``hidden'' integer accumulator is for computing the maximum or minimum of a set of values.

`maximize:M`

  binds `M` to a unary procedure to accumulate a maximum.

`minimum:M`

  similar but to accumulate a minimum

Note that `minimum` and `maximum` can both be used in the same loop to update the value of the hidden accumulator. Feature `default` can be used to provide a default value in case nothing is accumulated. Feature `return` can also be used to return an arbitrary value in exceptional cases.

### 2.4.2 Summing Values

Another way to use the integer accumulator is for computing the sum of a sequence of values.

`sum:S`

  The initial value of the accumulator is 0. Invoking `{S E}` adds `E` to the accumulator.

### 2.4.3 Multiplying Values

Same idea, but using multiplication

`multiply:M`

  The initial value of the accumulator is 1. Invoking `{M E}` multiplies the value of the accumulator by `E`.

## 2.5 Generators

A generator is a nullary function that returns the next value each time it is invoked, and raises an exception to indicate that all values have been exhausted (any exception will do, as long as it doesn't have label `error` or `failure`). Correspondingly, the folowing new iterator syntax is introduced:

`X from G`

  where `G` is a generator.