Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Are functions in Rust first class objects?

Tags:

rust

Can functions be passed as arguments? For example, in JavaScript you can pass a function as an argument like this:

setInterval(function() { /*...*/ }, 1000);
like image 701
Sho Ogihara Avatar asked Jul 26 '14 15:07

Sho Ogihara


People also ask

Is a function a first-class object?

In Python, functions behave like any other object, such as an int or a list. That means that you can use functions as arguments to other functions, store functions as dictionary values, or return a function from another function.

Why are functions called first class objects?

A programming language is said to have First-class functions when functions in that language are treated like any other variable. For example, in such a language, a function can be passed as an argument to other functions, can be returned by another function and can be assigned as a value to a variable.

What are functions in Rust?

Functions are the building blocks of readable, maintainable, and reusable code. A function is a set of statements to perform a specific task. Functions organize the program into logical blocks of code.

What does functions are first class citizens mean?

Basically, first-class citizenship simply means “being able to do what everyone else can do.” In JavaScript, functions are objects (hence the designation of first-class object). They inherit from the Object prototype and they can be assigned key: value pairs.


2 Answers

Anonymous functions like function() {} in JavaScript do exist in Rust, and you can define them using the closure syntax

|arg, arg2, arg3| {
  /* function body including optionally closed-over variables */
} 

Notice that the argument and return types are inferred!

Whether they are first class or not demands a little more exploration. By default, closed-over variables will be borrowed by the function. You can specify that those values be moved into the function using a move closure:

let num = 5;
let plus_num = move |x: i32| x + num;

Importantly, closures that do not reference their environment, which includes move closures, do not require references to the stack frame that created them. Since their sizes aren't known, they aren't first class objects by themselves.

You can Box a closure and return it as a trait object of the Fn trait.

This answer a brief summary of what's in the book which explains how closures are desugared and how they interact with the environment.

like image 28
Nate Avatar answered Oct 11 '22 11:10

Nate


They are first class. In contrast to JavaScript, Rust has two types - functions and closures.

fn first_class() {
    println!("function");
}

fn higher_kinded<F: FnOnce()>(cb: F) {
    cb();
}

fn main() {
    higher_kinded(first_class); // passing function
    higher_kinded(|| println!("closure")); // passing closure
}
like image 50
PEPP Avatar answered Oct 11 '22 13:10

PEPP