Functional Programming Functions

Kitty Giraudel on

For library makers and framework builders, having a couple of extra functions to dynamically apply functions to items of a list might come in handy. Here are 4 functions inspired by JavaScript and PHP equivalents, implemented in Sass.

walk()

The walk() function applies a given function to every item of a list.

/// Apply `$function` with `$args` to each item from `$list`. /// @author Kitty Giraudel /// @param {List} $list - List of items /// @param {String} $function - Function to apply to every item from `$list` /// @param {Arglist} $args - Extra arguments to pass to `$function` /// @return {List} /// @throw There is no `#{$function}` function. @function walk($list, $function, $args...) { @if not function-exists($function) { @error "There is no `#{$function}` function."; } @for $i from 1 through length($list) { $list: set-nth($list, $i, call($function, nth($list, $i), $args...)); } @return $list; }

Usage

walk { walk: walk(red green blue, invert); walk: walk(red green blue, lighten, 20%); walk: walk(2 4 6 8 10, sqrt); }
walk { walk: cyan #ff7fff yellow; walk: #ff6666 #00e600 #6666ff; walk: 1.41421 2 2.44949 2.82843 3.16228; }

some()

The some() function returns whether some items from a list pass test given (as a function).

/// Return whether some items from `$list` passed `$function` test. /// @author Kitty Giraudel /// @param {List} $list - List of items /// @param {String} $function - Function to run on every item from `$list` /// @param {Arglist} $args - Extra arguments to pass to `$function` /// @return {Boolean} /// @throw There is no `#{$function}` function. @function some($list, $function, $args...) { @if not function-exists($function) { @error "There is no `#{$function}` function."; } @each $item in $list { @if call($function, $item, $args...) { @return true; } } @return false; }

Usage

some { some: some(round ceil floor, function-exists); some: some(round ceil unknown, function-exists); some: some(completely unknown function, function-exists); some: some(4px 10px 20px, comparable, 42px); some: some(4px 10% 20px, comparable, 42%); some: some(4px 10px 20px, comparable, 42%); }
some { some: true; some: true; some: false; some: true; some: true; some: false; }

every()

The every() function returns whether every items from a list pass test given (as a function).

/// Return whether all items from `$list` passed `$function` test. /// @author Kitty Giraudel /// @param {List} $list - List of items /// @param {String} $function - Function to run on every item from `$list` /// @param {Arglist} $args - Extra arguments to pass to `$function` /// @return {Boolean} /// @throw There is no `#{$function}` function. @function every($list, $function, $args...) { @if not function-exists($function) { @error "There is no `#{$function}` function."; } @each $item in $list { @if not call($function, $item, $args...) { @return false; } } @return true; }

Usage

every { every: every(round ceil floor, function-exists); every: every(round ceil unknown, function-exists); every: every(completely unknown function, function-exists); every: every(4px 10px 20px, comparable, 42px); every: every(4px 10% 20px, comparable, 42%); every: every(4px 10px 20px, comparable, 42%); }
every { every: true; every: false; every: false; every: true; every: false; every: false; }

functions-walk()

The functions-walk() function returns a list made of the result of each function call.

/// Return a list made of the result of each function call from `$functions` with `$args`. /// @author Kitty Giraudel /// @param {List} $functions - List of functions to call /// @param {Arglist} $args - Extra arguments to pass to each function in `$functions` /// @return {List} /// @throw There is no `#{$function}` function. @function functions-walk($functions, $args...) { $list: (); @each $function in $functions { @if not function-exists($function) { @error "There is no `#{$function}` function."; } $list: append($list, call($function, $args...)); } @return $list; }

Usage

functions-walk { functions-walk: functions-walk('red' 'blue' 'green', #BADA55); functions-walk: functions-walk('round' 'ceil' 'floor', 3.1415279); }
functions-walk { functions-walk: 186 85 218; functions-walk: 3 4 3; }