Skip to content

Instantly share code, notes, and snippets.

@pdaoust
Last active April 5, 2023 11:07
Show Gist options
  • Star 6 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save pdaoust/7815423 to your computer and use it in GitHub Desktop.
Save pdaoust/7815423 to your computer and use it in GitHub Desktop.
Higher-order functions for Sass 3.3 -- now that we've got the `call()` function in Sass, we can start to compose functions. We don't have the benefit of anonymous functions, of course, but this is real functional programming, folks!
// 'map', 'transform', 'select', or 'project' function. Iterate over a list,
// performing a function on each item, and collecting the new items. Each
// function takes an item as a first argument and returns a transformed item.
// You can pass additional arguments to the function too, which is a decent poor
// man's function composition.
// (I didn't call this f-map because the term 'map' is already used in Sass to
// denote a hash or dictionary.)
@function f-apply($func, $list, $args...) {
$new-list: ();
@each $item in $list {
$new-list: append($new-list, call($func, $item, $args...));
}
@return $new-list;
}
// Reduce a list to a single value. Each function takes the previous value, an
// item, and additional arguments, and returns a transformed value. Sadly, you
// can't leave out the initial value (can't have default arguments before rest
// arguments), so if you don't want an initial value, set it to null.
@function f-fold($func, $list, $initial, $args...) {
$start: 1;
@if $initial == null {
// If there's no initial value, use the first in the list.
$start: 2;
$initial: nth($list, 1);
}
$prev: $initial;
@for $i from $start through length($list) {
$next: nth($list, $i);
$prev: call($func, $prev, $next, $args...);
}
@return $prev;
}
// Filter items from a list. Each function takes an item (and additional
// arguments) and returns a boolean value indicating whether the item passed the
// filter.
@function f-filter($func, $list, $args...) {
$new-list: ();
@each $item in $list {
@if call($func, $item, $args...) {
$new-list: append($new-list, $item);
}
}
@return $new-list;
}
@stereokai
Copy link

Fucking A, man. :)

@Justin-ZS
Copy link

Like it!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment