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")