Skip to content

Conversation

@Awjin
Copy link
Contributor

@Awjin Awjin commented Nov 25, 2019

First draft for specifying Sassified versions of all the mathematical functions in the Values and Units 4 Draft, logarithms, and $e and $pi variables.

See #851 for context.

Copy link
Contributor

@nex3 nex3 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a really good start!

@Awjin Awjin changed the base branch from master to proposal.forward-with.draft-1.1 November 27, 2019 22:16
@Awjin Awjin changed the base branch from proposal.forward-with.draft-1.1 to master November 27, 2019 22:16
Copy link
Contributor

@nex3 nex3 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Almost there!

hypot($numbers...)
```

* Throw an error if any argument is not a [length][].
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we don't allow unitless numbers here, I think that makes it the only Sass function that requires units. That's probably more confusing of an inconsistency than we'd have if we were more lenient than plain CSS and allowed unitless numbers here.

We could even go so far as to allow any compatible units here, since the output unit is always well-defined. I'm tempted to do so, because (unlike CSS) Sass allows custom units for which vector-length calculations could make sense.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, makes sense to me. I'll have hypot() accept any arguments that are all compatible with each other, and return a value that takes its unit from the leftmost argument.


* Throw an error if any argument is not a [length][].
* Return `Infinity` if any argument is `Infinity`.
* Return the square root of the sum of the squares of each argument.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All of these functions should define the units the return value uses, even if it's just "as a unitless number".

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Got it, fixed.

* Return `-Infinity` if `$number == 0`.
* Return `Infinity` if `$number == Infinity`.
* Return the [natural log][] of `$number`.
* Otherwise:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Style nit:

* Otherwise, if `$base < 0` or `$base == 0` or `$base == 1`, throw an error.
* Otherwise, return the natural log of `$number` divided by the natural log of `$base`.

Writing "Otherwise" for each branch of the conditional helps draw the reader's attention to the fact that there are three possible cases here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point. Fixed.

```

* Throw an error if `$number` has units or `$number < 0`.
* If `$base == null`:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Style nit for consistency with existing specs:

Suggested change
* If `$base == null`:
* If `$base` is null:

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, fixed.

* Return `1`.

* Otherwise, if `$exponent == Infinity`:
* Return `NaN` if the `absolute value of $base == 1`.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"Absolute value of" isn't really syntax, so it reads strange to have it code-highlighted... I'd probably either write this in prose:

Suggested change
* Return `NaN` if the `absolute value of $base == 1`.
* Return `NaN` if the absolute value of `$base` equals `1`.

or avoid mentioning absolute value altogether:

Suggested change
* Return `NaN` if the `absolute value of $base == 1`.
* Return `NaN` if `$base == 1` or `$base == -1`.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Got it. I'll go with the latter.

unitless, it is assumed to be in radians.
* Return `NaN` if `$number == Infinity`.
* Return `-0` if `$number == -0`.
* Return `Infinity` if `$number == 90 +/- (360 * n)`, where `n` is any
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
* Return `Infinity` if `$number == 90 +/- (360 * n)`, where `n` is any
* Return `Infinity` if `$number % 360deg == 90deg`.

It's important to specify units here, since the values 90 and 360 don't mean anything on their own if $number is in radians.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.


> `atan2($y, $x)` is distinct from `atan($y / $x)` because it preserves the
> quadrant of the point in question. For example, `atan2(1, -1)` corresponds to
> the point `(-1, 1)` and returns `(0.75 * pi) rad`. In contrast, `atan(1 / -1)`
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider making these radian examples valid SassScript:

Suggested change
> the point `(-1, 1)` and returns `(0.75 * pi) rad`. In contrast, `atan(1 / -1)`
> the point `(-1, 1)` and returns `0.75rad * $pi`. In contrast, `atan(1 / -1)`

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes sense, thanks.

Comment on lines 232 to 236
> `atan2($y, $x)` is distinct from `atan($y / $x)` because it preserves the
> quadrant of the point in question. For example, `atan2(1, -1)` corresponds to
> the point `(-1, 1)` and returns `(0.75 * pi) rad`. In contrast, `atan(1 / -1)`
> and `atan(-1 / 1)` resolve first to `atan(-1)`, so both return (`-0.25 * pi)
> rad`.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a really good explanation 👍.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks 🙂

Copy link
Contributor

@nex3 nex3 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great work!

* If all arguments are not compatible with each other, throw an error.
* Let the unit of the return value be the same as that of the leftmost argument
that has a unit. If all arguments are unitless, let the return value be
unitless.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What do you think about forbidding mixing unitless numbers with numbers that have units? The lack of transitivity there is weird, and while it's probably too late to change it for + and -, we could definitely change it here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The only reason I considered allowing unitless numbers was to model the behavior after +/- 🙂 But if the lack of transitivity is undesired, I'm good with forbidding mixing unitless/units.

@Awjin
Copy link
Contributor Author

Awjin commented Nov 28, 2019

Thanks for the reviews!

@nex3 nex3 merged commit 338532b into sass:master Dec 3, 2019
@tylermenezes tylermenezes mentioned this pull request Dec 3, 2019
5 tasks
@Awjin Awjin deleted the more-math-functions branch December 3, 2019 16:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants