Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What's the origin of -> in Rust function definition return types?

Tags:

rust

Rust uses colons to separate identifiers from types, like in

let x: u8 = 1;

However, for function return types -> is used instead. Example:

fn f() -> u8 { ... }

One might expect it to use a colon here as well:

fn f(): u8 { ... }

While using arrows has some precedence (e.g. in Haskell), I'm curious about the historical reason behind this choice. In addition, I'm also curious if it's a purely aesthetic reason or if using an arrow has some technical reason e.g. in simplifying parsing.

like image 226
tibbe Avatar asked Jan 26 '16 16:01

tibbe


People also ask

What is return in Rust?

A return marks the end of an execution path in a function: fn foo() -> i32 { return 3; } assert_eq!( foo(), 3); return is not needed when the returned value is the last expression in the function.

Is there a return keyword in Rust?

Return valueThe return keyword can be used to return a value inside a function's body. When this keyword isn't used, the last expression is implicitly considered to be the return value. If a function returns a value, its return type is specified in the signature using -> after the parentheses () .

How do you define a function in Rust?

We define a function in Rust by entering fn followed by a function name and a set of parentheses. The curly brackets tell the compiler where the function body begins and ends. We can call any function we've defined by entering its name followed by a set of parentheses.

What is function signature in Rust?

The function signature describes the types of formal parameters and return values along with other details that are needed to call a function correctly. A signature can optionally include ISA-specific ABI information which specifies exactly how arguments and return values are passed.


1 Answers

Well, I’m only guessing, but I’d say that the reason is purely aesthetic. : is often pronounced as “has the type”, while -> is pronounced as “to”. So f: fn(i32) -> i32 means “f has the type of functions from i32 to i32”.

Basically, there are two contexts where the return value of a function can be mentioned:

  1. Function item declaration:

    fn foo(x: i32) -> i32 {
      …
    }
    
  2. Assignment of a function to a variable with explicit type:

    let f: fn(x: i32) -> i32 = foo;
    

While using colon instead of arrow wouldn’t hurt readability in the first case, it would definitely do so in the second one. And it makes perfect sense to have the same symbol in both contexts.

The ultimate origin of this arrow is Simply Typed Lambda Calculus where this arrow is used as the function type constructor. From there it came to Haskell, Scala (well, not exactly, they use =>) and other languages.

like image 133
kirelagin Avatar answered Oct 20 '22 18:10

kirelagin