# Language extensions introduced in Batteries Included

Several language extensions and convenience features are introduced in Batteries Included. To take advantage of these features, please see the corresponding chapter.

## Comprehension expressions

(activated by default, implemented as findlib package `batteries.pa_comprehension.syntax`)
(designed for Batteries)
A list comprehension syntax for batteries, using enumerations by default.

### Output, generators and guards

The global form is `[? output | comp_item ; comp_item ; ... ?]`.
output is an expression and a comp_item is either a guard (a boolean expression), or a generator of the form `pattern <- expression`. Variables bound in the pattern can be used in the following comprehension items, and in the output expression.

Example :

    let pythagorean_triples n =
      [? (a,b,c) | a <- 1--n; b <- a--n; c <- b--n; a*a + b*b = c*c ?]

### Module parametrization

By default, the output in an enumeration, and generator expressions are assumed to be enumerations. It is possible to choose a different data structure with the `module : expression` syntax.

Examples :

    let positive_array_of_enum e =
      [? Array : n | n <- e; n > 0 ?]

    let combine la lb =
      [? List : (a, b) | a <- List : la; b <- List : lb ?]

Comprehension expressions rely on the presence in the given module of the following operations (where `'a t` represents the data-structure type : `'a array`, `'a Enum.t`...) :

    val filter : ('a -> bool) -> 'a t -> 'a t
    val concat : 'a t t -> 'a t
    val map : ('a -> 'b) -> 'a t -> 'b t
    val filter_map : ('a -> 'b option) -> 'a t -> 'b t (* used for refutable patterns in generators *)

    val enum : 'a t -> 'a Enum.t
    val of_enum : 'a Enum.t -> 'a t

If your module does not provide the first four operations but only the enum conversion functions, you could still benefit from the comprehension syntax by using eg. `foo <- Mod.enum bar` instead of `foo <- Mod : bar`.

## String syntax

(activated by default, implemented as findlib package `batteries.pa_string.syntax`)
(part of estring, adapted for Batteries by the author)
As Batteries offers several new types of strings, this extension provides the necessary syntactic sugar to manipulate unicode strings naturally.

### Text values

Declaring a Rope is as simple as

    let foo = r"Some Unicode text (Latin-1 encoded)"
    let bar = ur"Some Unicode text (UTF-8 encoded)"

This defines a new value `foo`, with type `Rope.t`, the type of (immutable) Unicode ropes. Of course, this manipulation doesn't have to happen at the highest-level:

    let append_string_to_rope x = Rope.append x (r"Some more Unicode text")

Note that ropes, being immutable, are automatically optimized, i.e. this is equivalent to

    let some_unique_name = Rope.of_latin1 "Some more Unicode text"
    let append_string_to_rope x = Rope.append x some_unique_name

It is possible to use the same syntax to define

Mutable UTF-8 strings
  e.g. `u"Some UTF-8 string"`, with type `UTF8.t`
Immutable Latin 1 strings (with capabilities)
  e.g. `ro"Some read-only string"`, with type `[`Read] String.Cap.t`
Mutable Latin 1 strings (with capabilities)
  e.g. `rw"Some read-write string"`, with type `[`Read | `Write] String.Cap.t`
Write-only Latin 1 strings (with capabilities)
  e.g. `wo"Some write-only string"`, with type `[`Write] String.Cap.t`

Again, immutable latin-1 strings are automatically optimized.

### Text patterns

The same syntax may be used to pattern-match against ropes, UTF-8 strings and string with capabilities.

## Lazy List syntax

##

A few new constructs are added to make using lazy lists easier. As an expression, `[%]` is a shortcut for `lazy BatLazyList.Nil`, the empty lazy list.

For pattern matching, the empty lazy list can be matched in the same way; `| [%]` matches `lazy BatLazyList.Nil`. To destructure lazy lists, `| a %:: b` is the same as `lazy BatLazyList.Cons(a,b)`.

`

# Summary of new keywords

- `where`, defined by pa_where

`