Skip to content

Commit

Permalink
Merge pull request #615 from sharkdp/fix-unit_of-crashes
Browse files Browse the repository at this point in the history
Fix unit_of-related crashes
  • Loading branch information
sharkdp authored Oct 11, 2024
2 parents 66cbea5 + 2196090 commit 885f763
Show file tree
Hide file tree
Showing 5 changed files with 25 additions and 22 deletions.
20 changes: 10 additions & 10 deletions book/src/list-functions-other.md
Original file line number Diff line number Diff line change
Expand Up @@ -89,36 +89,36 @@ fn is_finite<T: Dim>(n: T) -> Bool

Defined in: `core::quantities`

### `unit_of`
Extract the unit of a quantity (the `km/h` in `20 km/h`). This can be useful in generic code, but should generally be avoided otherwise.
### `value_of`
Extract the plain value of a quantity (the `20` in `20 km/h`). This can be useful in generic code, but should generally be avoided otherwise.

```nbt
fn unit_of<T: Dim>(x: T) -> T
fn value_of<T: Dim>(x: T) -> Scalar
```

<details>
<summary>Examples</summary>

<pre><div class="buttons"><button class="fa fa-play play-button" title="Run this code" aria-label="Run this code" onclick=" window.open('https://numbat.dev/?q=unit%5Fof%2820%20km%2Fh%29')""></button></div><code class="language-nbt hljs numbat">>>> unit_of(20 km/h)
<pre><div class="buttons"><button class="fa fa-play play-button" title="Run this code" aria-label="Run this code" onclick=" window.open('https://numbat.dev/?q=value%5Fof%2820%20km%2Fh%29')""></button></div><code class="language-nbt hljs numbat">>>> value_of(20 km/h)

= 1 km/h [Velocity]
= 20
</code></pre>

</details>

### `value_of`
Extract the plain value of a quantity (the `20` in `20 km/h`). This can be useful in generic code, but should generally be avoided otherwise.
### `unit_of`
Extract the unit of a quantity (the `km/h` in `20 km/h`). This can be useful in generic code, but should generally be avoided otherwise. Returns an error if the quantity is zero.

```nbt
fn value_of<T: Dim>(x: T) -> Scalar
fn unit_of<T: Dim>(x: T) -> T
```

<details>
<summary>Examples</summary>

<pre><div class="buttons"><button class="fa fa-play play-button" title="Run this code" aria-label="Run this code" onclick=" window.open('https://numbat.dev/?q=value%5Fof%2820%20km%2Fh%29')""></button></div><code class="language-nbt hljs numbat">>>> value_of(20 km/h)
<pre><div class="buttons"><button class="fa fa-play play-button" title="Run this code" aria-label="Run this code" onclick=" window.open('https://numbat.dev/?q=unit%5Fof%2820%20km%2Fh%29')""></button></div><code class="language-nbt hljs numbat">>>> unit_of(20 km/h)

= 20
= 1 km/h [Velocity]
</code></pre>

</details>
Expand Down
2 changes: 0 additions & 2 deletions examples/tests/core.nbt
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
# unit_of

assert_eq(unit_of(0), 1)

assert_eq(unit_of(1), 1)
assert_eq(unit_of(1.2345), 1)

Expand Down
4 changes: 3 additions & 1 deletion examples/tests/numerics.nbt
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,9 @@ assert_eq(fixed_point(f_sqrt3, 1, 1e-10), sqrt(3), 1e-10)
# Differentiation

assert_eq(diff(log, 2.0), 0.5, 1e-5)
assert_eq(diff(sin, 0.0), 1.0, 1e-5)

# TODO: Sadly, the following is not possible at the moment. See https://github.com/sharkdp/numbat/issues/521 for details
# assert_eq(diff(sin, 0.0), 1.0, 1e-5)

assert_eq(diff(sqrt, 1.0), 0.5, 1e-5)

Expand Down
12 changes: 7 additions & 5 deletions numbat/modules/core/quantities.nbt
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
use core::scalar

@description("Extract the unit of a quantity (the `km/h` in `20 km/h`). This can be useful in generic code, but should generally be avoided otherwise.")
@example("unit_of(20 km/h)")
fn unit_of<T: Dim>(x: T) -> T
use core::error

@description("Extract the plain value of a quantity (the `20` in `20 km/h`). This can be useful in generic code, but should generally be avoided otherwise.")
@example("value_of(20 km/h)")
fn value_of<T: Dim>(x: T) -> Scalar = x / unit_of(x)
fn value_of<T: Dim>(x: T) -> Scalar

@description("Extract the unit of a quantity (the `km/h` in `20 km/h`). This can be useful in generic code, but should generally be avoided otherwise. Returns an error if the quantity is zero.")
@example("unit_of(20 km/h)")
fn unit_of<T: Dim>(x: T) -> T = if x_value == 0 then error("…") else x / value_of(x)
where x_value = value_of(x)
9 changes: 5 additions & 4 deletions numbat/src/ffi/functions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ pub(crate) fn functions() -> &'static HashMap<String, ForeignFunction> {

// Core
insert_function!(error, 1..=1);
insert_function!(unit_of, 1..=1);
insert_function!(value_of, 1..=1);

// Math
insert_function!("mod", mod_, 2..=2);
Expand Down Expand Up @@ -118,7 +118,8 @@ fn error(mut args: Args) -> Result<Value> {
Err(RuntimeError::UserError(arg!(args).unsafe_as_string()))
}

fn unit_of(mut args: Args) -> Result<Value> {
let input_unit = quantity_arg!(args).unit().clone();
return_quantity!(1.0, input_unit)
fn value_of(mut args: Args) -> Result<Value> {
let quantity = quantity_arg!(args);

return_scalar!(quantity.unsafe_value().to_f64())
}

0 comments on commit 885f763

Please sign in to comment.