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

feat(stdlib): Add Number.tan, Number.factorial, Number.clamp, Number.lerp #1373

Closed
wants to merge 7 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions compiler/test/stdlib/number.test.gr
Original file line number Diff line number Diff line change
Expand Up @@ -256,3 +256,23 @@ assert Number.sin(20) > 0.91294 && Number.sin(20) < 0.91295
assert Number.cos(1) > 0.5403 && Number.cos(1) < 0.5404
assert Number.cos(-1) > 0.5403 && Number.cos(-1) < 0.5404
assert Number.cos(15) < -0.7596 && Number.cos(15) > -0.7597

// Number.tan
assert Number.tan(1) > 1.5574 && Number.tan(1) < 1.5575
assert Number.tan(-1) > -1.5575 && Number.tan(-1) < -1.5574
assert Number.tan(15) < -0.8559 && Number.tan(15) > -0.8560
// Number.factorial
assert Number.factorial(0) == 1
assert Number.factorial(1) == 1
assert Number.factorial(5) == 120
assert Number.factorial(10) == 3628800
assert Number.factorial(20) == 2432902008176640000
// Number.clamp
assert Number.clamp(0, 5, 0) == 0
assert Number.clamp(-5, 5, -10) == -5
assert Number.clamp(-5, 5, 6) == 5
assert Number.clamp(-5, 5, 5.5) == 5
// Number.lerp
assert Number.lerp(0, 5, 0) == 0
assert Number.lerp(0, 5, 0.5) == 2.5
assert Number.lerp(0, 5, 1) == 5
66 changes: 63 additions & 3 deletions stdlib/number.gr
Original file line number Diff line number Diff line change
Expand Up @@ -27,21 +27,21 @@ import Tags from "runtime/unsafe/tags"

/**
* Pi represented as a Number value.
*
*
* @since v0.5.2
*/
export let pi = 3.141592653589793

/**
* Tau represented as a Number value.
*
*
* @since v0.5.2
*/
export let tau = 6.283185307179586

/**
* Euler's number represented as a Number value.
*
*
* @since v0.5.2
*/
export let e = 2.718281828459045
Expand Down Expand Up @@ -439,3 +439,63 @@ export let sin = (radians: Number) => {
export let cos = (radians: Number) => {
sin(pi / 2 + radians)
}

/**
* Computes the tangent of a number (in radians) using Chebyshev polynomials.
*
* @param radians: The input in radians
* @returns The computed tangent
*
* @since v0.5.3
*/
export let tan = (radians: Number) => {
sin(radians) / cos(radians)
}

/**
* Computes the factorial of a number.
*
* @param input: The number to compute the factorial of, Must be a Non negative integer
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
* @param input: The number to compute the factorial of, Must be a Non negative integer
* @param input: The non-negative integer used to compute the factorial

* @returns The computed factorial
*
* @since v0.5.3
*/
export let factorial = input => {
spotandjake marked this conversation as resolved.
Show resolved Hide resolved
// Error If It is Negative, or Not an Integer
if (sign(input) is -1 || isInteger(input)) {
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
if (sign(input) is -1 || isInteger(input)) {
if (input < 0 || isInteger(input)) {

this is better, right?

fail "Factorial Expects A Non Negative Integer Input"
Copy link
Member

Choose a reason for hiding this comment

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

Do we actually want to fail or return an option? @ospencer

Copy link
Member

Choose a reason for hiding this comment

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

It should fail. If we really don't want it to fail then we can take Jake's suggestion to define this as the gamma function for non-integers.

} else {
// Factorial Helper
let rec fact = n => if (n is 0) 1 else n * fact(n - 1)
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
let rec fact = n => if (n is 0) 1 else n * fact(n - 1)
let rec fact = n => if (n == 0) 1 else n * fact(n - 1)

why use is?

// Perform Factorial
fact(input)
}
}

/**
* Clamps a number to a given range.
*
* @param min: The minimum value in the range
* @param max: The maximum value in the range
Comment on lines +478 to +479
Copy link
Member

Choose a reason for hiding this comment

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

Did someone say Range?

* @param input: The number to clamp
* @returns The clamped number
*
* @since v0.5.3
*/
export let clamp = (min: Number, max: Number, input: Number) => {
if (input < min) min else if (input > max) max else input
}

/**
* Linearly interpolates between the starting and ending value by the given amount.
*
* @param start: The starting value
* @param end: The ending value
* @param amount: an amount between 0 and 1, anything outside the range will produce an extrapolation i.e `lerp(0, 100, 2)` will produce 200
Copy link
Member

Choose a reason for hiding this comment

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

this is a "interpolation" but you are saying that it also "exptrapolates". I don't like that.

* @returns The interpolated value
*
* @since v0.5.3
*/
export let lerp = (start: Number, end: Number, amount: Number) => {
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
export let lerp = (start: Number, end: Number, amount: Number) => {
export let linearInterpret = (start: Number, end: Number, amount: Number) => {

Hear me out. lerp sounds like I'm 🤮

(end - start) * amount + start
}
104 changes: 104 additions & 0 deletions stdlib/number.md
Original file line number Diff line number Diff line change
Expand Up @@ -660,3 +660,107 @@ Returns:
|----|-----------|
|`Number`|The computed cosine|

### Number.**tan**

<details disabled>
<summary tabindex="-1">Added in <code>next</code></summary>
No other changes yet.
</details>

```grain
tan : Number -> Number
```

Computes the tangent of a number (in radians) using Chebyshev polynomials.

Parameters:

|param|type|description|
|-----|----|-----------|
|`radians`|`Number`|The input in radians|

Returns:

|type|description|
|----|-----------|
|`Number`|The computed tangent|

### Number.**factorial**

<details disabled>
<summary tabindex="-1">Added in <code>next</code></summary>
No other changes yet.
</details>

```grain
factorial : Number -> Number
```

Computes the factorial of a number.

Parameters:

|param|type|description|
|-----|----|-----------|
|`input`|`Number`|The number to compute the factorial of, Must be a Non negative integer|

Returns:

|type|description|
|----|-----------|
|`Number`|The computed factorial|

### Number.**clamp**

<details disabled>
<summary tabindex="-1">Added in <code>next</code></summary>
No other changes yet.
</details>

```grain
clamp : (Number, Number, Number) -> Number
```

Clamps a number to a given range.

Parameters:

|param|type|description|
|-----|----|-----------|
|`min`|`Number`|The minimum value in the range|
|`max`|`Number`|The maximum value in the range|
|`input`|`Number`|The number to clamp|

Returns:

|type|description|
|----|-----------|
|`Number`|The clamped number|

### Number.**lerp**

<details disabled>
<summary tabindex="-1">Added in <code>next</code></summary>
No other changes yet.
</details>

```grain
lerp : (Number, Number, Number) -> Number
```

Linearly interpolates between the starting and ending value by the given amount.

Parameters:

|param|type|description|
|-----|----|-----------|
|`start`|`Number`|The starting value|
|`end`|`Number`|The ending value|
|`amount`|`Number`|an amount between 0 and 1, anything outside the range will produce an extrapolation i.e `lerp(0, 100, 2)` will produce 200|

Returns:

|type|description|
|----|-----------|
|`Number`|The interpolated value|