# Functional utilities

To use the bindings from this module:

``````(import :std/misc/func)
``````

Collection of mixed purpose higher-order functions.

# always

``````(always val)            -> procedure
(always proc [arg ...]) -> procedure

val     := value that should always be returned
proc    := procedure that should always be called
arg ... := optional arguments that will be passed to proc
``````

Creates a lambda which returns the same `val` or calls always the same `proc` with the same optional `args`.

Examples:

``````> (def fn (always 5))
> (list (fn) (fn) (fn)))
(5 5 5)

> (def fn (always random-integer 10))
> [(fn) (fn) (fn)]
(4 3 8)
``````

# repeat

``````(repeat val n)            -> list
(repeat proc n [arg ...]) -> list

val     := value that should be repeated
proc    := proc that should be called n times
n       := exact number, repetitions
arg ... := optional arguments that will be passed to proc
``````

Repeat `val` or call `proc` with the optional `args` `n` times and return the result as list. `n` is expected to be an exact number.

Examples:

``````> (repeat 2 5)
(2 2 2 2 2)

> (repeat (lambda () 10) 3)
(10 10 10)

> (repeat random-integer 3 10)
(8 3 5)
``````

# compose1

``````(compose1 f1 f ...) -> procedure

f1, f ... := procedures
``````

Composes a sequence of unary functions; per the mathematical function composition the value flows right-to-left.

# rcompose1

``````(rcompose1 f1 f ...) -> procedure

f1, f ... := procedures
``````

Like `compose1`, but the value flows left-to-right.

# compose

``````(compose f1 f ...) -> procedure

f1, f ... := procedures
``````

Like `compose1`, but the composed function accepts multiple arguments.

Note: If you are composing unary functions, use `compose1`, as it avoids allocation from capturing arguments for apply.

# rcompose

``````(rcompose f1 f ...) -> procedure

f1, f ... := procedures
``````

Like `compose`, but the values flow left-to-right.

# compose/values

``````(compose/values f1 f ...) -> procedure

f1, f ... := procedures
``````

Like `compose`, but the composed function accepts multiple arguments and all functions can return multiple values, which are then applied as arguments to the next function in the sequence.

# rcompose/values

``````(rcompose/values f1 f ...) -> procedure

f1, f ... := procedures
``````

Like `compose/values`, but the values flow left-to-right.

# Functional composition macros

``````(@compose1 f1 f ...)
(@compose f1 f ...)
(@compose/values f1 f ...)
(@rcompose1 f1 f ...)
(@rcompose f1 f ...)
(@rcompose/values f1 f ...)
``````

These are macro versions of the functional composition operators; they generate significantly more efficient code and allow the optimizer to see through the composition.

# every-of

``````(every-of preds v [test: equal?]) -> boolean

preds := list of predicates or values
v     := value to compare with predicates
test  := optional, if preds contains a value, test is used for comparison
``````

`every-of` returns `#t` if all predicates match. If `preds` contains a non-predicate, it is transformed into one using `equal?` as test if not overridden by the `test:` keyword.

Examples:

``````> (every-of [number? fixnum?] 2)
#t

> (every-of [] 1)
#t

> (every-of [number? 10] 10 test: =)
#t
``````

# any-of

``````(any-of preds v [test: equal?]) -> boolean

preds := list of predicates or values
v     := value to compare with predicates
test  := optional, if preds contains a value, test is used for comparison
``````

`any-of` returns `#t` if one predicate matches. If `preds` contains a non-predicate, it is transformed into one using `equal?` as test if not overridden by the `test:` keyword.

Examples:

``````> (any-of [number? symbol?] 'a)
#t

> (any-of [] 1)
#f

> (any-of ['a 'b] 'b test: eq?)
#t
``````

# pred-limit

``````(pred-limit pred limit) -> procedure

pred  := predicate
limit := number of times pred is allowed to return a truthy value
``````

`pred-limit` returns a predicate which returns a truthy value only `limit` times, if `limit` is not false.

Examples:

``````> (filter (pred-limit even? 1) [1 2 3 4 5 6])
(2)

(def (myfilter pred list (limit #f))
(filter (pred-limit pred limit) list))

> (myfilter even? [1 2 3 4 5 6])
(2 4 6)

> (myfilter even? [1 2 3 4 5 6] 2)
(2 4)

> (myfilter even? [1 2 3 4 5 6] 0)
()
``````

# pred-sequence

``````(pred-sequence lst [limit = #f]) -> procedure

lst   := proper or circular list
limit := optional, return #t only limit times
``````

`pred-sequence` returns a predicate which returns `#t` on the last element of a matching sequence. The list elements are compared using `equal?`. `#t` is returned `limit` times, if `limit` is not `#f`.

Examples:

``````> (import (only-in :std/srfi/13 string-count))
> (string-count "ab_ab" (pred-sequence [#\a #\b]))
2

> (let (fn (pred-sequence [1 2]))
(fn 0)  ; #f
(fn 1)  ; #f
(fn 2)) ; #t
``````

# pred-and

``````(pred-and pred) -> procedure

pred  := predicate
``````

`pred-and` returns `#t` when every `pred` invocation returned a truethy value.

Examples:

``````> (let (fn (pred-and number?))
(fn 10)
(fn 20))
#t
``````

# pred-or

``````(pred-or pred) -> procedure

pred  := predicate
``````

`pred-or` returns `#t` when any `pred` invocation returned a truethy value.

Examples:

``````> (let (fn (pred-or number?))
(fn 'a)
(fn 20)
(fn "b"))
#t
``````

# pred-every-of

``````(pred-every-of preds [test: equal?]) -> procedure

preds := list of predicates or values
test  := optional, if preds contains a value, test is used for comparison
``````

`pred-every-of` returns a predicate which returns `#t` if all predicates match. If preds contains a non-predicate, it is transformed into one using `equal?` as test if not overridden by the `test:` keyword.

Examples:

``````> (filter (pred-every-of [number? fixnum?]) [1 'a 2.0 "b" 30])
(1 30)
``````

# pred-any-of

``````(pred-any-of preds [test: equal?]) -> procedure

preds := list of predicates or values
test  := optional, if preds contains a value, test is used for comparison
``````

`pred-any-of` returns a predicate which returns `#t` if one predicate matches. If preds contains a non-predicate, it is transformed into one using `equal?` as test if not overridden by the `test:` keyword.

Examples:

``````> (filter (pred-any-of [number? fixnum? "b"]) [1 'a 2.0 "b" 30])
(1 2. "b" 30)

> (import :std/sugar)
> (def files (directory-files))

> (filter (is path-extension (pred-any-of [".jpg" ".jpeg" ".png"])) files)
("xkcd_lisp.jpg" "logo.png")
``````