1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243
|
---
layout: default
permalink: docs/functions.html
---
# Functions
Stylus features powerful in-language function definitions. Function definitions appear identical to mixins; however, functions may return a value.
## Return Values
Let's try a trivial example: creating a function that adds two numbers.
add(a, b)
a + b
We can then use this function in conditions, in property values, etc.
body
padding add(10px, 5)
Rendering:
body {
padding: 15px;
}
## Argument Defaults
Optional arguments may default to a given expression. With Stylus we may even default arguments to earlier arguments!
For example:
add(a, b = a)
a + b
add(10, 5)
// => 15
add(10)
// => 20
**Note:** Since argument defaults are assignments, we can also use function calls for defaults:
add(a, b = unit(a, px))
a + b
## Named Parameters
Functions accept named parameters. This frees you from remembering the order of parameters, or simply improves the readability of your code.
For example:
subtract(a, b)
a - b
subtract(b: 10, a: 25)
## Function Bodies
We can take our simple `add()` function further. Let's casting all units passed as `px` via the `unit()` built-in. It reassigns each argument, and provides a unit-type string (or identifier), which ignores unit conversion.
add(a, b = a)
a = unit(a, px)
b = unit(b, px)
a + b
add(15%, 10deg)
// => 25
## Multiple Return Values
Stylus functions can return several values—just as you can assign several values to a variable.
For example, the following is a valid assignment:
sizes = 15px 10px
sizes[0]
// => 15px
Similarly, we may return several values:
sizes()
15px 10px
sizes()[0]
// => 15px
One slight exception is when return values are identifiers. For example, the following looks like a property assignment to Stylus (since no operators are present):
swap(a, b)
b a
To disambiguate, we can either wrap with parentheses, or use the `return` keyword:
swap(a, b)
(b a)
swap(a, b)
return b a
## Conditionals
Let's say we want to create a function named `stringish()` to determine whether the argument can be transformed to a string. We check if `val` is a string, or an ident (which is string-like). Because undefined identifiers yield themselves as the value, we may compare them to themselves as shown below (where `yes` and `no` are used in place of `true` and `false`):
stringish(val)
if val is a 'string' or val is a 'ident'
yes
else
no
Usage:
stringish('yay') == yes
// => true
stringish(yay) == yes
// => true
stringish(0) == no
// => true
__note__: `yes` and `no` are not boolean literals. They are simply undefined identifiers in this case.
Another example:
compare(a, b)
if a > b
higher
else if a < b
lower
else
equal
Usage:
compare(5, 2)
// => higher
compare(1, 5)
// => lower
compare(10, 10)
// => equal
## Aliasing
To alias a function, simply assign a function's name to a new identifier. For example, our `add()` function could be aliased as `plus()`, like so:
plus = add
plus(1, 2)
// => 3
## Variable Functions
In the same way that we can "alias" a function, we can pass a function as well. Here, our `invoke()` function accepts a function, so we can pass it `add()` or `sub()`.
add(a, b)
a + b
sub(a, b)
a - b
invoke(a, b, fn)
fn(a, b)
body
padding invoke(5, 10, add)
padding invoke(5, 10, sub)
Yielding:
body {
padding: 15;
padding: -5;
}
## Anonymous functions
You can use anonymous functions where needed using `@(){}` syntax. Here is how you could use it to create a custom `sort()` function:
sort(list, fn = null)
// default sort function
if fn == null
fn = @(a, b) {
a > b
}
// bubble sort
for $i in 1..length(list) - 1
for $j in 0..$i - 1
if fn(list[$j], list[$i])
$temp = list[$i]
list[$i] = list[$j]
list[$j] = $temp
return list
sort('e' 'c' 'f' 'a' 'b' 'd')
// => 'a' 'b' 'c' 'd' 'e' 'f'
sort(5 3 6 1 2 4, @(a, b){
a < b
})
// => 6 5 4 3 2 1
## arguments
The `arguments` local is available to all function bodies, and contains all the arguments passed.
For example:
sum()
n = 0
for num in arguments
n = n + num
sum(1,2,3,4,5)
// => 15
## Hash Example
Below we define the `get(hash, key)` function, which returns the
value of `key` (or `null`). We iterate each `pair` in `hash`, returning the pair's second node when the first (the `key`) matches.
get(hash, key)
return pair[1] if pair[0] == key for pair in hash
As demonstrated below, in-language functions—paired with robust Stylus expressions—can provide great flexibility:
hash = (one 1) (two 2) (three 3)
get(hash, two)
// => 2
get(hash, three)
// => 3
get(hash, something)
// => null
|