From 456e2a8ee339d165315168308f6c0e18cd51d32f Mon Sep 17 00:00:00 2001 From: Antoine Stevan <44101798+amtoine@users.noreply.github.com> Date: Tue, 5 Sep 2023 19:32:31 +0200 Subject: [PATCH] move math constants to standard library (#9678) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit # Description we talked about this before in some meetings so i thought, why not? the hope is that these constants do not require Rust code to be implemented and that this move will make the Rust source base a bit smaller :crossed_fingers: # User-Facing Changes mathematical constants (e, pi, tau, phi and gamma) are now in `std math` rather than `math` ## what can be done ```nushell > use std; $std.math > use std math; $math > use std *; $math ``` will all give ``` ╭───────┬────────────────────╮ │ GAMMA │ 0.5772156649015329 │ │ E │ 2.718281828459045 │ │ PI │ 3.141592653589793 │ │ TAU │ 6.283185307179586 │ │ PHI │ 1.618033988749895 │ ╰───────┴────────────────────╯ ``` and the following will work too ```nushell > use std math E; $E 2.718281828459045 ``` ```nushell > use std math *; $GAMMA 0.5772156649015329 ``` ## what can NOT be done looks like every export works fine now :relieved: # Tests + Formatting # After Submitting --- crates/nu-cmd-extra/src/example_test.rs | 5 -- crates/nu-cmd-extra/src/extra/math/cos.rs | 2 +- crates/nu-cmd-extra/src/extra/math/egamma.rs | 64 -------------------- crates/nu-cmd-extra/src/extra/math/euler.rs | 59 ------------------ crates/nu-cmd-extra/src/extra/math/ln.rs | 2 +- crates/nu-cmd-extra/src/extra/math/mod.rs | 10 --- crates/nu-cmd-extra/src/extra/math/phi.rs | 64 -------------------- crates/nu-cmd-extra/src/extra/math/pi.rs | 59 ------------------ crates/nu-cmd-extra/src/extra/math/sin.rs | 2 +- crates/nu-cmd-extra/src/extra/math/tan.rs | 2 +- crates/nu-cmd-extra/src/extra/math/tanh.rs | 2 +- crates/nu-cmd-extra/src/extra/math/tau.rs | 59 ------------------ crates/nu-cmd-extra/src/extra/mod.rs | 8 --- crates/nu-std/src/lib.rs | 1 + crates/nu-std/std/math.nu | 5 ++ 15 files changed, 11 insertions(+), 333 deletions(-) delete mode 100644 crates/nu-cmd-extra/src/extra/math/egamma.rs delete mode 100644 crates/nu-cmd-extra/src/extra/math/euler.rs delete mode 100644 crates/nu-cmd-extra/src/extra/math/phi.rs delete mode 100644 crates/nu-cmd-extra/src/extra/math/pi.rs delete mode 100644 crates/nu-cmd-extra/src/extra/math/tau.rs create mode 100644 crates/nu-std/std/math.nu diff --git a/crates/nu-cmd-extra/src/example_test.rs b/crates/nu-cmd-extra/src/example_test.rs index 8ee7f1b1bf..082080f8f9 100644 --- a/crates/nu-cmd-extra/src/example_test.rs +++ b/crates/nu-cmd-extra/src/example_test.rs @@ -15,8 +15,6 @@ mod test_examples { check_example_input_and_output_types_match_command_signature, }; - use crate::MathEuler; - use crate::MathPi; use nu_protocol::{ engine::{Command, EngineState, StateWorkingSet}, Type, @@ -64,9 +62,6 @@ mod test_examples { working_set.add_decl(Box::new(nu_command::Enumerate)); working_set.add_decl(Box::new(nu_cmd_lang::If)); - // math commands - working_set.add_decl(Box::new(MathEuler)); - working_set.add_decl(Box::new(MathPi)); working_set.add_decl(Box::new(nu_command::MathRound)); // Adding the command that is being tested to the working set diff --git a/crates/nu-cmd-extra/src/extra/math/cos.rs b/crates/nu-cmd-extra/src/extra/math/cos.rs index 75b17de4fc..b9d6da10e4 100644 --- a/crates/nu-cmd-extra/src/extra/math/cos.rs +++ b/crates/nu-cmd-extra/src/extra/math/cos.rs @@ -54,7 +54,7 @@ impl Command for SubCommand { vec![ Example { description: "Apply the cosine to π", - example: "math pi | math cos", + example: "3.141592 | math cos | math round --precision 4", result: Some(Value::test_float(-1f64)), }, Example { diff --git a/crates/nu-cmd-extra/src/extra/math/egamma.rs b/crates/nu-cmd-extra/src/extra/math/egamma.rs deleted file mode 100644 index f78ccccabd..0000000000 --- a/crates/nu-cmd-extra/src/extra/math/egamma.rs +++ /dev/null @@ -1,64 +0,0 @@ -use nu_protocol::ast::Call; -use nu_protocol::engine::{Command, EngineState, Stack}; -use nu_protocol::{ - Category, Example, IntoPipelineData, PipelineData, ShellError, Signature, Type, Value, -}; - -#[allow(clippy::excessive_precision)] -/// The Euler-Mascheroni constant (γ) -pub const EGAMMA: f64 = 0.577215664901532860606512090082402431_f64; - -#[derive(Clone)] -pub struct SubCommand; - -impl Command for SubCommand { - fn name(&self) -> &str { - "math egamma" - } - - fn signature(&self) -> Signature { - Signature::build("math egamma") - .input_output_types(vec![(Type::Any, Type::Float)]) - .category(Category::Math) - } - - fn usage(&self) -> &str { - "Returns the Euler–Mascheroni constant γ. ( 1 | math egamma)." - } - - fn search_terms(&self) -> Vec<&str> { - vec!["euler", "constant", "gamma"] - } - - #[allow(clippy::approx_constant)] - fn examples(&self) -> Vec { - vec![Example { - example: "math egamma | math round --precision 3", - description: "Get the first three decimal digits of γ", - result: Some(Value::test_float(0.577)), - }] - } - - fn run( - &self, - _engine_state: &EngineState, - _stack: &mut Stack, - call: &Call, - _input: PipelineData, - ) -> Result { - // TODO: replace with std::f64::consts::EGAMMA when available https://github.com/rust-lang/rust/issues/103883 - Ok(Value::float(EGAMMA, call.head).into_pipeline_data()) - } -} - -#[cfg(test)] -mod test { - use super::*; - - #[test] - fn test_examples() { - use crate::test_examples; - - test_examples(SubCommand {}) - } -} diff --git a/crates/nu-cmd-extra/src/extra/math/euler.rs b/crates/nu-cmd-extra/src/extra/math/euler.rs deleted file mode 100644 index d56544e4c8..0000000000 --- a/crates/nu-cmd-extra/src/extra/math/euler.rs +++ /dev/null @@ -1,59 +0,0 @@ -use nu_protocol::ast::Call; -use nu_protocol::engine::{Command, EngineState, Stack}; -use nu_protocol::{ - Category, Example, IntoPipelineData, PipelineData, ShellError, Signature, Type, Value, -}; - -#[derive(Clone)] -pub struct SubCommand; - -impl Command for SubCommand { - fn name(&self) -> &str { - "math e" - } - - fn signature(&self) -> Signature { - Signature::build("math e") - .input_output_types(vec![(Type::Any, Type::Float)]) - .category(Category::Math) - } - - fn usage(&self) -> &str { - "Returns the mathematical constant e (exp(1)/'1 | math exp')." - } - - fn search_terms(&self) -> Vec<&str> { - vec!["euler", "number", "constant"] - } - - #[allow(clippy::approx_constant)] - fn examples(&self) -> Vec { - vec![Example { - example: "math e | math round --precision 3", - description: "Get the first three decimal digits of e", - result: Some(Value::test_float(2.718)), - }] - } - - fn run( - &self, - _engine_state: &EngineState, - _stack: &mut Stack, - call: &Call, - _input: PipelineData, - ) -> Result { - Ok(Value::float(std::f64::consts::E, call.head).into_pipeline_data()) - } -} - -#[cfg(test)] -mod test { - use super::*; - - #[test] - fn test_examples() { - use crate::test_examples; - - test_examples(SubCommand {}) - } -} diff --git a/crates/nu-cmd-extra/src/extra/math/ln.rs b/crates/nu-cmd-extra/src/extra/math/ln.rs index cd953978ff..24d261cdc0 100644 --- a/crates/nu-cmd-extra/src/extra/math/ln.rs +++ b/crates/nu-cmd-extra/src/extra/math/ln.rs @@ -52,7 +52,7 @@ impl Command for SubCommand { fn examples(&self) -> Vec { vec![Example { description: "Get the natural logarithm of e", - example: "math e | math ln", + example: "2.7182818 | math ln | math round --precision 4", result: Some(Value::test_float(1.0f64)), }] } diff --git a/crates/nu-cmd-extra/src/extra/math/mod.rs b/crates/nu-cmd-extra/src/extra/math/mod.rs index 35e2fcc20d..6da13a181c 100644 --- a/crates/nu-cmd-extra/src/extra/math/mod.rs +++ b/crates/nu-cmd-extra/src/extra/math/mod.rs @@ -5,13 +5,8 @@ mod sinh; mod tan; mod tanh; -mod egamma; -mod euler; mod exp; mod ln; -mod phi; -mod pi; -mod tau; mod arccos; mod arccosh; @@ -27,13 +22,8 @@ pub use sinh::SubCommand as MathSinH; pub use tan::SubCommand as MathTan; pub use tanh::SubCommand as MathTanH; -pub use egamma::SubCommand as MathEulerGamma; -pub use euler::SubCommand as MathEuler; pub use exp::SubCommand as MathExp; pub use ln::SubCommand as MathLn; -pub use phi::SubCommand as MathPhi; -pub use pi::SubCommand as MathPi; -pub use tau::SubCommand as MathTau; pub use arccos::SubCommand as MathArcCos; pub use arccosh::SubCommand as MathArcCosH; diff --git a/crates/nu-cmd-extra/src/extra/math/phi.rs b/crates/nu-cmd-extra/src/extra/math/phi.rs deleted file mode 100644 index 56b0dee9b1..0000000000 --- a/crates/nu-cmd-extra/src/extra/math/phi.rs +++ /dev/null @@ -1,64 +0,0 @@ -use nu_protocol::ast::Call; -use nu_protocol::engine::{Command, EngineState, Stack}; -use nu_protocol::{ - Category, Example, IntoPipelineData, PipelineData, ShellError, Signature, Type, Value, -}; - -#[allow(clippy::excessive_precision)] -/// The golden ratio (φ) -pub const PHI: f64 = 1.618033988749894848204586834365638118_f64; - -#[derive(Clone)] -pub struct SubCommand; - -impl Command for SubCommand { - fn name(&self) -> &str { - "math phi" - } - - fn signature(&self) -> Signature { - Signature::build("math phi") - .input_output_types(vec![(Type::Any, Type::Float)]) - .category(Category::Math) - } - - fn usage(&self) -> &str { - "Returns the golden ratio φ. ( (1 + sqrt(5) ) / 2 )" - } - - fn search_terms(&self) -> Vec<&str> { - vec!["golden", "ratio", "constant"] - } - - #[allow(clippy::approx_constant)] - fn examples(&self) -> Vec { - vec![Example { - example: "math phi | math round --precision 3", - description: "Get the first two decimal digits of φ", - result: Some(Value::test_float(1.618)), - }] - } - - fn run( - &self, - _engine_state: &EngineState, - _stack: &mut Stack, - call: &Call, - _input: PipelineData, - ) -> Result { - // TODO: replace with std::f64::consts::PHI when available https://github.com/rust-lang/rust/issues/103883 - Ok(Value::float(PHI, call.head).into_pipeline_data()) - } -} - -#[cfg(test)] -mod test { - use super::*; - - #[test] - fn test_examples() { - use crate::test_examples; - - test_examples(SubCommand {}) - } -} diff --git a/crates/nu-cmd-extra/src/extra/math/pi.rs b/crates/nu-cmd-extra/src/extra/math/pi.rs deleted file mode 100644 index fb3aba2673..0000000000 --- a/crates/nu-cmd-extra/src/extra/math/pi.rs +++ /dev/null @@ -1,59 +0,0 @@ -use nu_protocol::ast::Call; -use nu_protocol::engine::{Command, EngineState, Stack}; -use nu_protocol::{ - Category, Example, IntoPipelineData, PipelineData, ShellError, Signature, Type, Value, -}; - -#[derive(Clone)] -pub struct SubCommand; - -impl Command for SubCommand { - fn name(&self) -> &str { - "math pi" - } - - fn signature(&self) -> Signature { - Signature::build("math pi") - .input_output_types(vec![(Type::Any, Type::Float)]) - .category(Category::Math) - } - - fn usage(&self) -> &str { - "Returns the mathematical constant π." - } - - fn search_terms(&self) -> Vec<&str> { - vec!["trigonometry", "constant"] - } - - #[allow(clippy::approx_constant)] - fn examples(&self) -> Vec { - vec![Example { - example: "math pi | math round --precision 2", - description: "Get the first two decimal digits of π", - result: Some(Value::test_float(3.14)), - }] - } - - fn run( - &self, - _engine_state: &EngineState, - _stack: &mut Stack, - call: &Call, - _input: PipelineData, - ) -> Result { - Ok(Value::float(std::f64::consts::PI, call.head).into_pipeline_data()) - } -} - -#[cfg(test)] -mod test { - use super::*; - - #[test] - fn test_examples() { - use crate::test_examples; - - test_examples(SubCommand {}) - } -} diff --git a/crates/nu-cmd-extra/src/extra/math/sin.rs b/crates/nu-cmd-extra/src/extra/math/sin.rs index def2d7deda..25dcadf3d8 100644 --- a/crates/nu-cmd-extra/src/extra/math/sin.rs +++ b/crates/nu-cmd-extra/src/extra/math/sin.rs @@ -54,7 +54,7 @@ impl Command for SubCommand { vec![ Example { description: "Apply the sine to π/2", - example: "(math pi) / 2 | math sin", + example: "3.141592 / 2 | math sin | math round --precision 4", result: Some(Value::test_float(1f64)), }, Example { diff --git a/crates/nu-cmd-extra/src/extra/math/tan.rs b/crates/nu-cmd-extra/src/extra/math/tan.rs index b24c17ddf8..0aad4376c9 100644 --- a/crates/nu-cmd-extra/src/extra/math/tan.rs +++ b/crates/nu-cmd-extra/src/extra/math/tan.rs @@ -54,7 +54,7 @@ impl Command for SubCommand { vec![ Example { description: "Apply the tangent to π/4", - example: "(math pi) / 4 | math tan", + example: "3.141592 / 4 | math tan | math round --precision 4", result: Some(Value::test_float(1f64)), }, Example { diff --git a/crates/nu-cmd-extra/src/extra/math/tanh.rs b/crates/nu-cmd-extra/src/extra/math/tanh.rs index aec6d8b404..fb0f3f7ede 100644 --- a/crates/nu-cmd-extra/src/extra/math/tanh.rs +++ b/crates/nu-cmd-extra/src/extra/math/tanh.rs @@ -52,7 +52,7 @@ impl Command for SubCommand { fn examples(&self) -> Vec { vec![Example { description: "Apply the hyperbolic tangent to 10*π", - example: "(math pi) * 10 | math tanh", + example: "3.141592 * 10 | math tanh | math round --precision 4", result: Some(Value::test_float(1f64)), }] } diff --git a/crates/nu-cmd-extra/src/extra/math/tau.rs b/crates/nu-cmd-extra/src/extra/math/tau.rs deleted file mode 100644 index d18e8458e4..0000000000 --- a/crates/nu-cmd-extra/src/extra/math/tau.rs +++ /dev/null @@ -1,59 +0,0 @@ -use nu_protocol::ast::Call; -use nu_protocol::engine::{Command, EngineState, Stack}; -use nu_protocol::{ - Category, Example, IntoPipelineData, PipelineData, ShellError, Signature, Type, Value, -}; - -#[derive(Clone)] -pub struct SubCommand; - -impl Command for SubCommand { - fn name(&self) -> &str { - "math tau" - } - - fn signature(&self) -> Signature { - Signature::build("math tau") - .input_output_types(vec![(Type::Any, Type::Float)]) - .category(Category::Math) - } - - fn usage(&self) -> &str { - "Returns the mathematical constant τ." - } - - fn search_terms(&self) -> Vec<&str> { - vec!["trigonometry", "constant"] - } - - #[allow(clippy::approx_constant)] - fn examples(&self) -> Vec { - vec![Example { - example: "math tau | math round --precision 2", - description: "Get the first two decimal digits of τ", - result: Some(Value::test_float(6.28)), - }] - } - - fn run( - &self, - _engine_state: &EngineState, - _stack: &mut Stack, - call: &Call, - _input: PipelineData, - ) -> Result { - Ok(Value::float(std::f64::consts::TAU, call.head).into_pipeline_data()) - } -} - -#[cfg(test)] -mod test { - use super::*; - - #[test] - fn test_examples() { - use crate::test_examples; - - test_examples(SubCommand {}) - } -} diff --git a/crates/nu-cmd-extra/src/extra/mod.rs b/crates/nu-cmd-extra/src/extra/mod.rs index c8d189a930..e88adba999 100644 --- a/crates/nu-cmd-extra/src/extra/mod.rs +++ b/crates/nu-cmd-extra/src/extra/mod.rs @@ -24,13 +24,8 @@ pub use math::MathSinH; pub use math::MathTan; pub use math::MathTanH; -pub use math::MathEuler; -pub use math::MathEulerGamma; pub use math::MathExp; pub use math::MathLn; -pub use math::MathPhi; -pub use math::MathPi; -pub use math::MathTau; pub use math::MathArcCos; pub use math::MathArcCosH; @@ -111,9 +106,6 @@ pub fn add_extra_command_context(mut engine_state: EngineState) -> EngineState { MathSinH, MathCosH, MathTanH, - MathPi, - MathTau, - MathEuler, MathExp, MathLn }; diff --git a/crates/nu-std/src/lib.rs b/crates/nu-std/src/lib.rs index 5c1e9237dd..0e5948da29 100644 --- a/crates/nu-std/src/lib.rs +++ b/crates/nu-std/src/lib.rs @@ -27,6 +27,7 @@ pub fn load_standard_library( ("assert.nu", include_str!("../std/assert.nu")), ("xml.nu", include_str!("../std/xml.nu")), ("input.nu", include_str!("../std/input.nu")), + ("math.nu", include_str!("../std/math.nu")), ]; let mut working_set = StateWorkingSet::new(engine_state); diff --git a/crates/nu-std/std/math.nu b/crates/nu-std/std/math.nu new file mode 100644 index 0000000000..cbfc7253ca --- /dev/null +++ b/crates/nu-std/std/math.nu @@ -0,0 +1,5 @@ +export const GAMMA = 0.5772156649015329 +export const E = 2.718281828459045 +export const PI = 3.141592653589793 +export const TAU = 6.283185307179586 +export const PHI = 1.618033988749895