Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore(docs): Add examples to Number module #2015

Merged
merged 3 commits into from Mar 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
142 changes: 142 additions & 0 deletions stdlib/number.gr
Expand Up @@ -16,6 +16,13 @@
*
* @example from "number" include Number
*
* @example 1
* @example -1
* @example 0.5
* @example 1/2
* @example Infinity
* @example NaN
*
* @since v0.4.0
*/
module Number
Expand Down Expand Up @@ -70,6 +77,10 @@ provide let e = 2.718281828459045
* @param num2: The second operand
* @returns The sum of the two operands
*
* @example
* from Number use { (+) }
* assert 1 + 2 == 3
*
* @since v0.6.0
* @history v0.4.0: Originally named `add`
*/
Expand All @@ -82,6 +93,10 @@ provide let (+) = (+)
* @param num2: The second operand
* @returns The difference of the two operands
*
* @example
* from Number use { (-) }
* assert 5 - 2 == 3
*
* @since v0.6.0
* @history v0.4.0: Originally named `sub`
*/
Expand All @@ -94,6 +109,10 @@ provide let (-) = (-)
* @param num2: The second operand
* @returns The product of the two operands
*
* @example
* from Number use { (*) }
* assert 5 * 4 == 20
*
* @since v0.6.0
* @history v0.4.0: Originally named `mul`
*/
Expand All @@ -106,6 +125,10 @@ provide let (*) = (*)
* @param num2: The divisor
* @returns The quotient of the two operands
*
* @example
* from Number use { (/) }
* assert 10 / 2.5 == 4
*
* @since v0.6.0
* @history v0.4.0: Originally named `div`
*/
Expand All @@ -118,6 +141,10 @@ provide let (/) = (/)
* @param power: The exponent number
* @returns The base raised to the given power
*
* @example
* from Number use { (**) }
* assert 10 ** 2 == 100
*
* @since v0.6.0
* @history v0.5.4: Originally named `pow`
*/
Expand All @@ -129,17 +156,23 @@ provide let (**) = (**)
* @param power: The exponent number
* @returns The `Number.e` value raised to the given power
*
* @example Number.exp(1) == Number.e
* @example Number.exp(10) == 22026.465794806703
*
* @since v0.5.4
*/
provide let exp = power => {
if (power == 0) 1 else e ** power
}

/**
* Computes the square root of its operand.
*
* @param x: The number to square root
* @returns The square root of the operand
*
* @example Number.sqrt(25) == 5
*
* @since v0.4.0
*/
@unsafe
Expand All @@ -164,6 +197,8 @@ provide let sqrt = (x: Number) => {
* @example Number.sign(-10000) == -1
* @example Number.sign(222222) == 1
* @example Number.sign(0) == 0
*
* @since v0.5.0
*/
provide let sign = x => {
match (x) {
Expand All @@ -180,6 +215,8 @@ provide let sign = x => {
* @param y: The second operand
* @returns The smaller of the two operands
*
* @example Number.min(5, 2) == 2
*
* @since v0.4.0
* @history v0.5.4: Handle NaN properly
*/
Expand All @@ -192,6 +229,8 @@ provide let min = (x: Number, y: Number) => if (compare(x, y) < 0) x else y
* @param y: The second operand
* @returns The larger of the two operands
*
* @example Number.max(5, 2) == 5
*
* @since v0.4.0
* @history v0.5.4: Handle NaN properly
*/
Expand All @@ -203,6 +242,9 @@ provide let max = (x: Number, y: Number) => if (compare(x, y) > 0) x else y
* @param x: The number to round
* @returns The next largest integer of the operand
*
* @example Number.ceil(5.5) == 6
* @example Number.ceil(-5.5) == -5
*
* @since v0.4.0
* @history v0.5.4: Handle NaN and Infinity properly
*/
Expand All @@ -225,6 +267,9 @@ provide let ceil = (x: Number) => {
* @param x: The number to round
* @returns The previous integer of the operand
*
* @example Number.floor(5.5) == 5
* @example Number.floor(-5.5) == -6
*
* @since v0.4.0
* @history v0.5.4: Handle NaN and Infinity properly
*/
Expand All @@ -247,6 +292,8 @@ provide let floor = (x: Number) => {
* @param x: The number to truncate
* @returns The integer part of the operand
*
* @example Number.trunc(5.5) == 5
*
* @since v0.4.0
* @history v0.5.4: Handle NaN and Infinity properly
*/
Expand All @@ -269,6 +316,11 @@ provide let trunc = (x: Number) => {
* @param x: The number to round
* @returns The nearest integer to the operand
*
* @example Number.round(5.5) == 6
* @example Number.round(5.4) == 5
* @example Number.round(-5.5) == -6
* @example Number.round(-5.4) == -5
*
* @since v0.4.0
* @history v0.5.4: Handle NaN and Infinity properly
*/
Expand All @@ -291,6 +343,9 @@ provide let round = (x: Number) => {
* @param x: The operand
* @returns The absolute value of the operand
*
* @example Number.abs(-1) == 1
* @example Number.abs(5) == 5
*
* @since v0.4.0
*/
provide let abs = (x: Number) => if (0 > x) x * -1 else x
Expand All @@ -301,6 +356,9 @@ provide let abs = (x: Number) => if (0 > x) x * -1 else x
* @param x: The number to negate
* @returns The negated operand
*
* @example Number.neg(-1) == 1
* @example Number.neg(1) == -1
*
* @since v0.4.0
*/
provide let neg = (x: Number) => x * -1
Expand All @@ -311,6 +369,13 @@ provide let neg = (x: Number) => x * -1
* @param x: The number to check
* @returns `true` if the value is a floating point number or `false` otherwise
*
* @example Number.isFloat(0.5)
* @example Number.isFloat(1.0)
* @example Number.isFloat(Infinity)
* @example Number.isFloat(NaN)
* @example Number.isFloat(1/2) == false
* @example Number.isFloat(1) == false
*
* @since v0.5.3
*/
@unsafe
Expand All @@ -324,6 +389,13 @@ provide let isFloat = (x: Number) => {
* @param x: The number to check
* @returns `true` if the value is an integer or `false` otherwise
*
* @example Number.isInteger(1)
* @example Number.isInteger(0.5) == false
* @example Number.isInteger(1.0) == false
* @example Number.isInteger(1/2) == false
* @example Number.isInteger(Infinity) == false
* @example Number.isInteger(NaN) == false
*
* @since v0.5.3
*/
@unsafe
Expand All @@ -337,6 +409,13 @@ provide let isInteger = (x: Number) => {
* @param x: The number to check
* @returns `true` if the value is a non-integer rational number or `false` otherwise
*
* @example Number.isRational(1/2)
Copy link
Member

Choose a reason for hiding this comment

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

No == true here?

* @example Number.isRational(0.5) == false
* @example Number.isRational(1.0) == false
* @example Number.isRational(1) == false
* @example Number.isRational(Infinity) == false
* @example Number.isRational(NaN) == false
*
* @since v0.5.3
*/
@unsafe
Expand All @@ -351,6 +430,14 @@ provide let isRational = (x: Number) => {
* @param x: The number to check
* @returns `true` if the value is finite or `false` otherwise
*
* @example Number.isFinite(1/2)
* @example Number.isFinite(0.5)
* @example Number.isFinite(1.0)
* @example Number.isFinite(1)
Comment on lines +433 to +436
Copy link
Member

Choose a reason for hiding this comment

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

And these?

Copy link
Member

Choose a reason for hiding this comment

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

Or is this our style? Just feels a little weird since it's not an assertion.

Copy link
Member

Choose a reason for hiding this comment

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

I haven't been paying that close of attention. I know jake was doing assert in some cases.

Copy link
Member Author

Choose a reason for hiding this comment

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

We have been using assert semantics for single line matches throughout the stdlib.

Copy link
Member

Choose a reason for hiding this comment

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

@spotandjake why don't these contain assert then?

* @example Number.isFinite(Infinity) == false
* @example Number.isFinite(-Infinity) == false
* @example Number.isFinite(NaN) == false
*
* @since v0.4.0
*/
@unsafe
Expand Down Expand Up @@ -384,6 +471,14 @@ provide let isFinite = (x: Number) => {
* @param x: The number to check
* @returns `true` if the value is NaN, otherwise `false`
*
* @example Number.isNaN(NaN)
* @example Number.isNaN(Infinity) == false
* @example Number.isNaN(-Infinity) == false
* @example Number.isNaN(1/2) == false
* @example Number.isNaN(0.5) == false
* @example Number.isNaN(1.0) == false
* @example Number.isNaN(1) == false
*
* @since v0.4.0
*/
@unsafe
Expand All @@ -399,6 +494,14 @@ provide let isNaN = (x: Number) => {
* @param x: The number to check
* @returns `true` if the value is infinite or `false` otherwise
*
* @example Number.isInfinite(Infinity)
* @example Number.isInfinite(-Infinity)
* @example Number.isInfinite(NaN) == false
* @example Number.isInfinite(1/2) == false
* @example Number.isInfinite(0.5) == false
* @example Number.isInfinite(1.0) == false
* @example Number.isInfinite(1) == false
*
* @since v0.4.0
*/
@unsafe
Expand Down Expand Up @@ -430,6 +533,15 @@ provide let isInfinite = (x: Number) => {
* @param absoluteTolerance: The absolute tolerance to use, regardless of the values of `a` or `b`
* @returns `true` if the values are considered close to each other or `false` otherwise
*
* @example Number.isClose(1.233, 1.233)
* @example Number.isClose(1.233, 1.233000001)
* @example Number.isClose(8.005, 8.450, absoluteTolerance=0.5)
* @example Number.isClose(4, 4.1, relativeTolerance=0.025)
* @example Number.isClose(1.233, 1.24) == false
* @example Number.isClose(1.233, 1.4566) == false
* @example Number.isClose(8.005, 8.450, absoluteTolerance=0.4) == false
* @example Number.isClose(4, 4.1, relativeTolerance=0.024) == false
*
* @since v0.6.0
*/
provide let isClose = (a, b, relativeTolerance=1e-9, absoluteTolerance=0.0) => {
Expand Down Expand Up @@ -457,6 +569,10 @@ provide let isClose = (a, b, relativeTolerance=1e-9, absoluteTolerance=0.0) => {
* @param radix: The number system base to use when parsing the input string
* @returns `Ok(value)` containing the parsed number on a successful parse or `Err(msg)` containing an error message string otherwise
*
* @example Number.parseInt("1", radix=10) == Ok(1)
* @example Number.parseInt("-1", radix=10) == Ok(-1)
* @example Number.parseInt("0xf0", radix=16) == Ok(0x0f0)
*
* @since v0.4.5
*/
provide let parseInt = Atoi.parseInt
Expand All @@ -468,6 +584,10 @@ provide let parseInt = Atoi.parseInt
* @param string: The string to parse
* @returns `Ok(value)` containing the parsed number on a successful parse or `Err(msg)` containing an error message string otherwise
*
* @example Number.parseFloat("1") == Ok(1.0)
* @example Number.parseFloat("-1") == Ok(-1.0)
* @example Number.parseFloat("-1.5") == Ok(-1.5)
*
* @since v0.5.5
*/
provide let parseFloat = Atof.parseFloat
Expand All @@ -479,6 +599,11 @@ provide let parseFloat = Atof.parseFloat
* @param input: The string to parse
* @returns `Ok(value)` containing the parsed number on a successful parse or `Err(msg)` containing an error message string otherwise
*
* @example Number.parse("1") == Ok(1)
* @example Number.parse("-1") == Ok(-1)
* @example Number.parse("0xf0") == Ok(0x0f0)
* @example Number.parse("-1.5") == Ok(-1.5)
*
* @since v0.5.5
*/
@unsafe
Expand Down Expand Up @@ -573,12 +698,16 @@ let rf = z => {
let q = 1.0W + z * (qS1 + z * (qS2 + z * (qS3 + z * qS4)))
p / q
}

/**
* Computes the inverse sine of the given angle.
*
* @param angle: A number between -1 and 1, representing the angle's sine value
* @returns The inverse sine (angle in radians between `-pi/2` and `pi/2`) of the given `angle` or `NaN` if the given `angle` is not between`-1` and `1`
*
* @example Number.asin(0) == 0
* @example Number.asin(1) == 1.5707963267948966
*
* @since v0.6.0
*/
@unsafe
Expand Down Expand Up @@ -641,6 +770,9 @@ provide let asin = angle => {
* @param angle: A number between -1 and 1, representing the angle's cosine value
* @returns The inverse cosine (angle in radians between `-pi/2` and `pi/2`) of the given `angle` or `NaN` if the given `angle` is not between`-1` and `1`
*
* @example Number.acos(1) == 0
* @example Number.acos(0) == 1.5707963267948966
*
* @since v0.6.0
*/
@unsafe
Expand Down Expand Up @@ -707,6 +839,9 @@ provide let acos = angle => {
* @param angle: A number between -1 and 1, representing the angle's tangent value
* @returns The inverse tangent (angle in radians between `-pi/2` and `pi/2`) of the given `angle` or `NaN` if the given `angle` is not between`-1` and `1`
*
* @example Number.atan(0) == 0
* @example Number.atan(1) == 0.7853981633974483
*
* @since v0.6.0
*/
@unsafe
Expand Down Expand Up @@ -828,6 +963,8 @@ provide let atan2 = (y, x) => {
* @param degrees: The value to convert
* @returns The value in radians
*
* @example Number.toRadians(180) == Number.pi
*
* @since v0.5.4
*/
provide let toRadians = degrees => degrees * (pi / 180)
Expand All @@ -838,10 +975,13 @@ provide let toRadians = degrees => degrees * (pi / 180)
* @param radians: The value to convert
* @returns The value in degrees
*
* @example Number.toRadians(Number.pi) == 180
*
* @since v0.5.4
*/
provide let toDegrees = radians => radians * (180 / pi)

// TODO(#471): Add examples for clamp
/**
* Constrains a number within the given inclusive range.
*
Expand All @@ -868,6 +1008,7 @@ provide let clamp = (range, input) => {
}
}

// TODO(#471): Add examples for linearInterpolate
/**
* Maps a weight between 0 and 1 within the given inclusive range.
*
Expand All @@ -891,6 +1032,7 @@ provide let linearInterpolate = (range, weight) => {
(range.rangeEnd - range.rangeStart) * weight + range.rangeStart
}

// TODO(#471): Add examples for linearMap
/**
* Scales a number from one inclusive range to another inclusive range.
* If the number is outside the input range, it will be clamped.
Expand Down