Skip to content

Commit c29e625

Browse files
author
Awjin Ahn
authored
More Math Functions: Draft 2 (sass#2790)
1 parent 9babfc8 commit c29e625

File tree

2 files changed

+141
-58
lines changed

2 files changed

+141
-58
lines changed

proposal/more-math-functions.changes.md

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,25 @@
1+
## Draft 2
2+
3+
* Variables
4+
* `$e` and `$pi` have 1 more digit of precision after the decimal.
5+
* Variables from built-in modules cannot be modified.
6+
7+
* `Infinity` and `-Infinity`:
8+
* If any argument to `hypot()` equals `-Infinity`, it returns `Infinity`.
9+
* The `$exponent == Infinity` case in `pow()` also holds for
10+
`$exponent == -Infinity`.
11+
* The `$number == Infinity` cases in `cos()`, `sin()`, and `tan()` also hold
12+
for `$number == -Infinity`.
13+
14+
* Input units:
15+
* `clamp()`'s arguments must all have compatible units, or all be unitless.
16+
* `log()` does not error unless the input has units, and instead delegates
17+
edge cases to division.
18+
19+
* Output units:
20+
* For `acos()`, `asin()`, and `atan()`, and `atan2()`, all of their outputs
21+
are numbers in `deg`.
22+
123
## Draft 1.1
224

325
* Added Background and Summary sections.

proposal/more-math-functions.md

Lines changed: 119 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# More Math Functions: Draft 1.1
1+
# More Math Functions: Draft 2
22

33
*[(Issue)](https://github.com/sass/sass/issues/851)*
44

@@ -7,6 +7,8 @@ This proposal adds the following members to the built-in `sass:math` module.
77
## Table of Contents
88
* [Background](#background)
99
* [Summary](#summary)
10+
* [Semantics](#semantics)
11+
* [Built-in Module Variables](#built-in-module-variables)
1012
* [Variables](#variables)
1113
* [`$e`](#e)
1214
* [`$pi`](#pi)
@@ -60,7 +62,7 @@ unitless number.
6062
[angle]: https://drafts.csswg.org/css-values-4/#angles
6163

6264
The inverse trig functions—`acos()`, `asin()`, `atan()`—accept a unitless number
63-
and output a SassScript number in `rad`. `atan2()` is similar, but it accepts
65+
and output a SassScript number in `deg`. `atan2()` is similar, but it accepts
6466
two unitless numbers.
6567

6668
`clamp()` accepts three SassScript numbers with [compatible][] units: the
@@ -76,17 +78,73 @@ length of the `n`-dimensional vector that has components equal to each of the
7678
inputs. Since the inputs' units may all be different, the output takes the unit
7779
of the first input.
7880

81+
## Semantics
82+
83+
### Built-in Module Variables
84+
85+
Variables defined in built-in modules are not modifiable. As such, this proposal
86+
modifies the semantics of [Executing a Variable Declaration][] within the
87+
[Variables spec][] to read as follows:
88+
89+
[Executing a Variable Declaration]: ../spec/variables.md#executing-a-variable-declaration
90+
[Variables spec]: ../spec/variables.md
91+
92+
To execute a `VariableDeclaration` `declaration`:
93+
94+
* Let `value` be the result of evaluating `declaration`'s `Expression`.
95+
96+
* Let `name` be `declaration`'s `Variable`.
97+
98+
* **Let `resolved` be the result of [resolving a variable][] named `name`.**
99+
100+
[resolving a variable]: ../spec/modules.md#resolving-a-member
101+
102+
* If `name` is a `NamespacedVariable` and `declaration` has a `!global` flag,
103+
throw an error.
104+
105+
* **Otherwise, if `resolved` is a variable from a built-in module, throw an
106+
error.**
107+
108+
* Otherwise, if `declaration` is outside of any block of statements, *or*
109+
`declaration` has a `!global` flag, *or* `name` is a `NamespacedVariable`:
110+
111+
* ~~Let `resolved` be the result of [resolving a variable][] named `name` using
112+
`file`, `uses`, and `import`.~~
113+
114+
(...)
115+
116+
* Otherwise, if `declaration` is within one or more blocks associated with
117+
`@if`, `@each`, `@for`, and/or `@while` rules *and no other blocks*:
118+
119+
* ~~Let `resolved` be the result of [resolving a variable][] named `name`.~~
120+
121+
(...)
122+
123+
* ~~Otherwise, if no block containing `declaration` has a [scope][] with a
124+
variable named `name`, set the innermost block's scope's variable `name` to
125+
`value`.~~
126+
127+
[scope]: ../spec/variables.md#scope
128+
129+
* **Otherwise, if `resolved` is null, get the innermost block containing
130+
`declaration` and set its scope's variable `name` to `value`.**
131+
132+
* ~~Otherwise, let `scope` be the scope of the innermost block such that `scope`
133+
already has a variable named `name`.~~
134+
135+
* **Otherwise, set `resolved`'s value to `value`.**
136+
79137
## Variables
80138

81139
### `$e`
82140

83141
Equal to the value of the mathematical constant `e` with a precision of 10
84-
digits: `2.718281828`.
142+
digits after the decimal point: `2.7182818285`.
85143

86144
### `$pi`
87145

88146
Equal to the value of the mathematical constant `pi` with a precision of 10
89-
digits: `3.141592654`.
147+
digits after the decimal point: `3.1415926536`.
90148

91149
## Functions
92150

@@ -98,6 +156,7 @@ clamp($min, $number, $max)
98156

99157
* If the units of `$min`, `$number`, and `$max` are not compatible with each
100158
other, throw an error.
159+
* If some arguments have units and some do not, throw an error.
101160
* If `$min >= $max`, return `$min`.
102161
* If `$number <= $min`, return `$min`.
103162
* If `$number >= $max`, return `$max`.
@@ -113,7 +172,7 @@ hypot($arguments...)
113172
* If some arguments have units and some do not, throw an error.
114173
* If all arguments are unitless, the return value is unitless.
115174
* Otherwise, the return value takes the unit of the leftmost argument.
116-
* If any argument is `Infinity`, return `Infinity`.
175+
* If any argument equals `Infinity` or `-Infinity`, return `Infinity`.
117176
* Return the square root of the sum of the squares of each argument.
118177

119178
### Exponentiation
@@ -124,12 +183,12 @@ hypot($arguments...)
124183
log($number, $base: null)
125184
```
126185

127-
* If `$number` has units or `$number < 0`, throw an error.
186+
* If `$number` has units, throw an error.
128187
* If `$base` is null:
188+
* If `$number < 0`, return `NaN` as a unitless number.
129189
* If `$number == 0`, return `-Infinity` as a unitless number.
130190
* If `$number == Infinity`, return `Infinity` as a unitless number.
131191
* Return the [natural log][] of `$number`, as a unitless number.
132-
* Otherwise, if `$base < 0` or `$base == 0` or `$base == 1`, throw an error.
133192
* Otherwise, return the natural log of `$number` divided by the natural log of
134193
`$base`, as a unitless number.
135194

@@ -145,7 +204,7 @@ pow($base, $exponent)
145204

146205
* If `$exponent == 0`, return `1` as a unitless number.
147206

148-
* Otherwise, if `$exponent == Infinity`:
207+
* Otherwise, if `$exponent == Infinity` or `$exponent == -Infinity`:
149208
* If `$base == 1` or `$base == -1`, return `NaN` as a unitless number.
150209
* If `$base < -1` or `$base > 1` and if `$exponent > 0`, *or* if `$base > -1`
151210
and `$base < 1` and `$exponent < 0`, return `Infinity` as a
@@ -196,7 +255,8 @@ cos($number)
196255

197256
* If `$number` has units but is not an angle, throw an error.
198257
* If `$number` is unitless, treat it as though its unit were `rad`.
199-
* If `$number == Infinity`, return `NaN` as a unitless number.
258+
* If `$number == Infinity` or `$number == -Infinity`, return `NaN` as a unitless
259+
number.
200260
* Return the [cosine][] of `$number`, as a unitless number.
201261

202262
[cosine]: https://en.wikipedia.org/wiki/Trigonometric_functions#Right-angled_triangle_definitions
@@ -209,7 +269,8 @@ sin($number)
209269

210270
* If `$number` has units but is not an angle, throw an error.
211271
* If `$number` is unitless, treat it as though its unit were `rad`.
212-
* If `$number == Infinity`, return `NaN` as a unitless number.
272+
* If `$number == Infinity` or `$number == -Infinity`, return `NaN` as a unitless
273+
number.
213274
* If `$number == -0`, return `-0` as a unitless number.
214275
* Return the [sine][] of `$number`, as a unitless number.
215276

@@ -223,7 +284,8 @@ tan($number)
223284

224285
* If `$number` has units but is not an angle, throw an error.
225286
* If `$number` is unitless, treat it as though its unit were `rad`.
226-
* If `$number == Infinity`, return `NaN` as a unitless number.
287+
* If `$number == Infinity` or `$number == -Infinity`, return `NaN` as a unitless
288+
number.
227289
* If `$number == -0`, return `-0` as a unitless number.
228290
* If `$number` is equivalent to `90deg +/- 360deg * n`, where `n` is any
229291
integer, return `Infinity` as a unitless number.
@@ -240,9 +302,9 @@ acos($number)
240302
```
241303

242304
* If `$number` has units, throw an error.
243-
* If `$number < -1` or `$number > 1`, return `NaN` as a number in `rad`.
244-
* If `$number == 1`, return `0rad`.
245-
* Return the [arccosine][] of `$number`, as a number in `rad`.
305+
* If `$number < -1` or `$number > 1`, return `NaN` as a number in `deg`.
306+
* If `$number == 1`, return `0deg`.
307+
* Return the [arccosine][] of `$number`, as a number in `deg`.
246308

247309
[arccosine]: https://en.wikipedia.org/wiki/Inverse_trigonometric_functions#Basic_properties
248310

@@ -253,9 +315,9 @@ asin($number)
253315
```
254316

255317
* If `$number` has units, throw an error.
256-
* If `$number < -1` or `$number > 1`, return `NaN` as a number in `rad`.
257-
* If `$number == -0`, return `-0rad`.
258-
* Return the [arcsine][] of `$number`, as a number in `rad`.
318+
* If `$number < -1` or `$number > 1`, return `NaN` as a number in `deg`.
319+
* If `$number == -0`, return `-0deg`.
320+
* Return the [arcsine][] of `$number`, as a number in `deg`.
259321

260322
[arcsine]: https://en.wikipedia.org/wiki/Inverse_trigonometric_functions#Basic_properties
261323

@@ -266,29 +328,28 @@ atan($number)
266328
```
267329

268330
* If `$number` has units, throw an error.
269-
* If `$number == -0`, return `-0rad`.
270-
* If `$number == -Infinity`, return `-0.5rad * pi`.
271-
* If `$number == Infinity`, return `0.5rad * pi`.
272-
* Return the [arctangent][] of `$number`, as a number in `rad`.
331+
* If `$number == -0`, return `-0deg`.
332+
* If `$number == -Infinity`, return `-90deg`.
333+
* If `$number == Infinity`, return `90deg`.
334+
* Return the [arctangent][] of `$number`, as a number in `deg`.
273335

274336
[arctangent]: https://en.wikipedia.org/wiki/Inverse_trigonometric_functions#Basic_properties
275337

276338
#### `atan2()`
277339

278340
> `atan2($y, $x)` is distinct from `atan($y / $x)` because it preserves the
279341
> quadrant of the point in question. For example, `atan2(1, -1)` corresponds to
280-
> the point `(-1, 1)` and returns `0.75rad * pi`. In contrast, `atan(1 / -1)`
281-
> and `atan(-1 / 1)` resolve first to `atan(-1)`, so both return
282-
> `-0.25rad * pi`.
342+
> the point `(-1, 1)` and returns `135deg`. In contrast, `atan(1 / -1)` and
343+
> `atan(-1 / 1)` resolve first to `atan(-1)`, so both return `-45deg`.
283344
284345
```
285346
atan2($y, $x)
286347
```
287348

288349
* If `$y` and `$x` are not compatible, throw an error.
289350
* If the inputs match one of the following edge cases, return the provided
290-
number in `rad`. Otherwise, return the [2-argument arctangent][] of `$y` and
291-
`$x`, as a number in `rad`.
351+
number. Otherwise, return the [2-argument arctangent][] of `$y` and `$x`, as a
352+
number in `deg`.
292353

293354
[2-argument arctangent]: https://en.wikipedia.org/wiki/Atan2
294355

@@ -314,57 +375,57 @@ atan2($y, $x)
314375
<tr>
315376
<th rowspan="6">Y</th>
316377
<th>−Infinity</th>
317-
<td>-0.75 * pi</td>
318-
<td>-0.5 * pi</td>
319-
<td>-0.5 * pi</td>
320-
<td>-0.5 * pi</td>
321-
<td>-0.5 * pi</td>
322-
<td>-0.25 * pi</td>
378+
<td>-135deg</td>
379+
<td>-90deg</td>
380+
<td>-90deg</td>
381+
<td>-90deg</td>
382+
<td>-90deg</td>
383+
<td>-45deg</td>
323384
</tr>
324385
<tr>
325386
<th>-finite</th>
326-
<td>-pi</td>
387+
<td>-180deg</td>
327388
<td></td>
328-
<td>-0.5 * pi</td>
329-
<td>-0.5 * pi</td>
389+
<td>-90deg</td>
390+
<td>-90deg</td>
330391
<td></td>
331-
<td>-0</td>
392+
<td>-0deg</td>
332393
</tr>
333394
<tr>
334395
<th>-0</th>
335-
<td>-pi</td>
336-
<td>-pi</td>
337-
<td>-pi</td>
338-
<td>-0</td>
339-
<td>-0</td>
340-
<td>-0</td>
396+
<td>-180deg</td>
397+
<td>-180deg</td>
398+
<td>-180deg</td>
399+
<td>-0deg</td>
400+
<td>-0deg</td>
401+
<td>-0deg</td>
341402
</tr>
342403
<tr>
343404
<th>0</th>
344-
<td>pi</td>
345-
<td>pi</td>
346-
<td>pi</td>
347-
<td>0</td>
348-
<td>0</td>
349-
<td>0</td>
405+
<td>180deg</td>
406+
<td>180deg</td>
407+
<td>180deg</td>
408+
<td>0deg</td>
409+
<td>0deg</td>
410+
<td>0deg</td>
350411
</tr>
351412
<tr>
352413
<th>finite</th>
353-
<td>pi</td>
414+
<td>180deg</td>
354415
<td></td>
355-
<td>0.5 * pi</td>
356-
<td>0.5 * pi</td>
416+
<td>90deg</td>
417+
<td>90deg</td>
357418
<td></td>
358-
<td>0</td>
419+
<td>0deg</td>
359420
</tr>
360421
<tr>
361422
<th>Infinity</th>
362-
<td>0.75 * pi</td>
363-
<td>0.5 * pi</td>
364-
<td>0.5 * pi</td>
365-
<td>0.5 * pi</td>
366-
<td>0.5 * pi</td>
367-
<td>0.25 * pi</td>
423+
<td>135deg</td>
424+
<td>90deg</td>
425+
<td>90deg</td>
426+
<td>90deg</td>
427+
<td>90deg</td>
428+
<td>45deg</td>
368429
</tr>
369430
</tbody>
370431
</table>

0 commit comments

Comments
 (0)