Implement functional programming (Clojure syntax) in Sass. Dart Sass only.
Anonymous functions in lambda-sass are implemented using S-expressions, such as (plus 1 2 3)
, which is represented as the Sass list data type under the hood. When defining anonymous functions, you can use _
for a single parameter or _1
, _2
, and so on for multiple parameters.
Only Iterator Functions and Threading Functions accept anonymous functions as arguments. Here are some examples:
reduce((plus _1 _2 _2), "#", ["a", "b", "c"]) // "#aabbcc"
thread-last(1, inc, (plus 10 5), dec, ("math.pow" 2)) // 65536
As you may have noticed in the example above, it is necessary to enclose the method name in quotes when using the Sass built-in modules. Failure to do so will result in a syntax error. It's important to note that all Sass built-in modules are already pre-included, so there's no need to import the module using @use "sass:math"
at the beginning of your file.
It's exciting to have the ability to utilize the threading-like features of Clojure in Sass. In case you're not acquainted with threading macros, I recommend taking a look at this resource.
Many functions have two different ways of being called, known as arities: fn($list...)
and fn([$list])
. For instance, plus(1, 2, 3)
and plus([1, 2, 3])
both result in the value 6
.
Install lambda-sass
npm i -D lambda-sass
In vanilla projects, import the full path to lambda.scss
:
@use "path/to/node_modules/lambda-sass/src/lambda.scss" as *;
In some frameworks, like Next.js
, which utilize the webpack sass-loader
, it is possible to simply import the package name:
@use "lambda-sass" as *;
plus($list...)
or plus([$list])
plus(1, 2, 3) // 6
plus("#", "a", "b", "c") // "#abc"
plus([1, 2, 3]) // 6
plus(["#", "a", "b", "c"]) // "#abc"
minus($number...)
or minus([$number])
minus(1, 2, 3) // -4
minus([1, 2, 3]) // -4
multiply($number...)
or multiply([$number])
multiply(1, 2, 3) // 6
multiply([1, 2, 3]) // 6
divide($number...)
or divide([$number])
divide(1, 2, 3) // 0.16666666667
divide([1, 2, 3]) // 0.16666666667
Remainder of dividing numerator by denominator.
rem($base, $div)
rem(10, 3) // 1
rem(-10, 3) // 2
rem(10, -3) // -2
rem(-10, -3) // -1
Quotient of dividing numerator by denominator.
quot($base, $div)
quot(10, 3) // 3
quot(12, 3) // 4
quot(-5.9, 3) // -1
quot(10, -3) // -3
inc($number)
inc(1) // 2
dec($number)
dec(1) // 0
odd($number)
odd(1) // true
odd(2) // false
even($number)
even(1) // false
even(2) // true
greater($number...)
or greater([$number])
greater(1, 2, 3, 4) // false
greater(4, 3, 2, 1) // true
greater([1, 2, 3, 4]) // false
greater([4, 3, 2, 1]) // true
greater-equal($number...)
or greater-equal([$number])
greater-equal(1, 3, 3, 4) // false
greater-equal(4, 3, 3, 1) // true
greater-equal([1, 3, 3, 4]) // false
greater-equal([4, 3, 3, 1]) // true
less($number...)
or less([$number])
less(1, 2, 3, 4) // true
less(4, 3, 2, 1) // false
less([1, 2, 3, 4]) // true
less([4, 3, 2, 1]) // false
less-equal($number...)
or less-equal([$number])
less-equal(1, 3, 3, 4) // true
less-equal(4, 3, 3, 1) // false
less-equal([1, 3, 3, 4]) // true
less-equal([4, 3, 3, 1]) // false
equal($list...)
or equal([$list])
equal(1, 1, 1) // true
equal(1, 2, 3) // false
equal("a", "a", "a") // true
equal("a", "b", "c") // false
equal([1, 1, 1]) // true
equal([1, 2, 3]) // false
equal(["a", "a", "a"]) // true
equal(["a", "b", "c"]) // false
not-equal($list...)
or not-equal([$list])
not-equal(1, 1, 1) // false
not-equal(1, 2, 3) // true
not-equal("a", "a", "a") // false
not-equal("a", "b", "c") // true
not-equal([1, 1, 1]) // false
not-equal([1, 2, 3]) // true
not-equal(["a", "a", "a"]) // false
not-equal(["a", "b", "c"]) // true
first($list)
or first($string)
first([1, 2, 3]) // 1
first("#abc") // "#"
last($list)
or last($string)
last([1, 2, 3]) // 3
last("#abc") // "c"
rest($list)
or rest($string)
rest([1, 2, 3]) // (2, 3)
rest("#abc") // ("a", "b", "c")
reverse($list...)
or reverse([$list])
reverse(1, 2, 3, 4) // (4, 3, 2, 1)
reverse([1, 2, 3, 4]) // (4, 3, 2, 1)
range($start-from? = 0, $end-to, $step? = 1)
range(5) // (0 1 2 3 4)
range(-2, 5) // (-2 -1 0 1 2 3 4)
range(-2, 9, 3) // (-2 1 4 7)
repeat($value, $times)
repeat(1, 5) // (1 1 1 1 1)
repeat("a", 5) // ("a" "a" "a" "a" "a")
repeat(((1, 2), 5) // ((1, 2) (1, 2) (1, 2) (1, 2) (1, 2))
conj($list, $value)
conj(null, 1)); // [1]
conj([1, 2], 3); // [1, 2, 3]
conj([1, 2], [3, 4]); // [1, 2, 3, 4]
conj((a: 1, b: 2), (c: 3)); // (a: 1, b: 2, c: 3)
map($function, $list...)
or map($function, [$list])
map(inc, 1, 2, 3) // (2, 3, 4)
map((plus _ 1), 1, 2, 3) // (2, 3, 4)
map(inc, [1, 2, 3]) // (2, 3, 4)
map((plus _ 1), [1, 2, 3]) // (2, 3, 4)
filter($function, $list...)
or filter($function, [$list])
filter(odd, [1 2 3]) // (1 3)
filter((greater _ 1), [1 2 3]) // (2 3)
filter(odd, 1, 2, 3) // (1 3)
filter((greater _ 1), 1, 2, 3) // (2 3)
redure($function, $init-value, $list...)
or reduce($function, $init-value, [$list])
reduce((plus _1 _2), 0, 1, 2, 3) // 6
reduce((plus _1 _2 _2), "#", "a", "b", "c") // "#aabbcc"
reduce((plus _1 _2), 0, [1, 2, 3]) // 6
reduce((plus _1 _2 _2), "#", ["a", "b", "c"]) // "#aabbcc"
some($function, $list...)
or some($function, [$list])
some(even, -1, 0, 12) // true
some(even, -1, 3, 11) // false
some(even, [-1, 0, 12]) // true
some(even, [-1, 3, 11]) // false
every($function, $list...)
or every($function, [$list])
every(odd, -1, 3, 9) // true
every(odd, -1, 0, 9) // false
every(odd, [-1, 3, 9]) // true
every(odd, [-1, 0, 9]) // false
assoc($map, ($key, $value)...)
assoc((a: 1, b: 2), a, 3, b, 4) // (a: 3, b: 4)
assoc([1 2 3], 2, (a b)) // [1 (a b) 3]
assoc([1 2 3], 2, a, 3, b, 4, c, 5, d) // [1 a b c d]
assoc-in($map, [$key], $value)
assoc-in((a: (b: (c: 1, d: 2))), [a b c], 2) // (a: (b: (c: 2, d: 2)))
assoc-in((1 (a (a b)) 3), [2 2 2], a) // (1 (a (a a)) 3)
Same as the as->
macro in Clojure.
thread-as($init-value, $function...)
thread-as(1, inc, (plus 10 _ 5), dec, ("math.pow" _ 2)) // 256
Same as the ->
macro in Clojure.
thread-first($init-value, $function...)
thread-first(1, inc, (plus 10 5), dec, ("math.pow" 2)) // 256
Same as the ->>
macro in Clojure.
thread-last($init-value, $function...)
thread-last(1, inc, (plus 10 5), dec, ("math.pow" 2)) // 65536