Why is `sin` a method?

I have to respectfully disagree. Rust method notation looks very strange to me for mathematics, especially with functions that take multiple arguments, e.g. mul_add, atan2. It was technically convenient for Rust to use methods and that outweighed the burden of the change to very widely used mathematical notation.

1 Like

I prefer to write f64::sin(x) when calling the math methods.


But that's a different question. Writing Foo::method(foo) doesn't have any larger cognitive overhead by itself than writing foo.method().

1 Like

I am agree with you in calling a single function, but this would producing a terrible experience for calling three or more functions in a chain, because you need keep all the type information of each step returns in mind, and if the type or module is not in current scope, you need to import or quote it. This make me so tired in using functional languages.


Combining your (@alice's) answer and @vague's answer, you can apparently use:


Holy moly -- that's a lot of replies! Thanks everyone, I learned a bunch.

Worth noting (for my fellow noobs) that you have to add num as a dependency and declare extern crate num; in order to be able to do this, which is something you don't get from the playground link you shared.

You haven't needed that since edition 2018.

1 Like

That's a good point - and a tricky bit to the Rust playground, I guess. I didn't realize it was an external crate.

Huh! My library failed to compile for testing and the compiler said something about not knowing what num was and adding extern crate num; fixed it. Now that I remove the statement, however, it still compiles just fine. I have no idea!

Does your Cargo.toml have
edition = "2018"
edition = "2021"

I'm not encouraging you use the generic sin function. Use the one that meets your needs.

Don't worry! I didn't interpret your answer as encouraging one thing or another -- only as providing a potential solution to my use case.

There is no need to use an external crate by repeating extern crate[1] in 2021 edition: Preludes - The Rust Reference

Edition Differences: In the 2015 edition, crates in the extern prelude cannot be referenced via use declarations, so it is generally standard practice to include extern crate declarations to bring them into scope.

Beginning in the 2018 edition, use declarations can reference crates in the extern prelude, so it is considered unidiomatic to use extern crate.

  1. though there are niche tricks around extern crate ↩︎

1 Like

Indeed, as @quinedot has already pointed out:

The single exception I'm aware of is extern crate alloc in #![no_std] - are there others? Something with non-cargo builds?

The real usage of extern crate in the root of crate seems to define global items, so

  • extern crate a as b can give the crate a an alias b, and both a and b can be used to reference the same crate
    • so extern crate a as b acts like use a as b, but globally, which means
extern crate a as b;
use a as c;

mod m {
    // crate a and its alias b can be used in the submod, but alias c can't
  • extern crate self as alias can give the current crate a global alias. This is useful to unify the paths based on your crate name in macros, because you can't specify your crate name in your own crate without it, and an example for this.
    • use self as alias won't work and cause the error
error[E0429]: `self` imports are only allowed within a { } list
 --> src/main.rs:3:5
3 | use self as alias;
  |     ^^^^
  • #[macro_use] extern crate a can gobally import all the macros including both decl and proc macros in the root of crate a to your crate, and submods can use them directly.

You need extern crate for parts of Rust that are distributed by rustup as pre-compiled binaries because the compiler will link to the directly.

So things like alloc and core, as well as internal crates like rustc_driver and rustc_codegen_ssa.


This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.