Hacker News new | ask | show | jobs
by proto_lambda 1119 days ago
> That would not compile

It does compile.

> because `x` does not have the type `fn (i32, i32) -> i32` (that's reserved for "normal" functions).

Closures can cast to function pointers just fine as long as they don't capture anything.

4 comments

Closing over variables is the thing that makes it a closure. Otherwise, you just have an anonymous function. A closure is a function plus the captured environment.

The difference is meaningful here. You have to allocate a closure (and deal with its lifetime and the lifetimes of the variables it references) but the anonymous function is just a pointer to static code in the binary. That's the entire difficulty with closures in non-GC languages.

This distinction matters less in GC languages where you're not thinking about lifetimes either way.

As per Rust reference, even a capture-less closure is a closure and distinct from an anonymous functions.

Also, your arguments only partly apply in Rust. Rust doesn't heap-allocate closures. And you also often don't have to deal with lifetimes - a closure that captures variables by move or copy is perfectly self-contained

The difference between a closure that captures and a closure that doesn't is like the difference between `(T)` and `()` - same kind of thing, so it adheres to the same terms and behaviors

> You have to allocate a closure

That's incorrect, a closure in Rust compiles down to a static function that takes its environment as an argument. None of that requires a heap allocation in the above code.

Stack allocation is still allocation.
Literally no considers that to be the case? Like I have never met anyone who would consider declaring an integer variable "allocation"
Write a compiler sometime; it'll be more obvious why the term of art is "stack allocation" instead of something that doesn't include the word "allocation." You'll understand why C's "alloca" function and C#'s "stackalloc" keyword are named like that. Stack overflows will make more sense--obviously you can't allocate forever, because you are indeed allocating memory.

As a parting gift, I'll give you one guess what the title of the Wikipedia article on thread stacks is.

https://en.wikipedia.org/wiki/Stack-based_memory_allocation

I didn't suggest a heap allocation; indeed, in C++ too you can have stack allocated closures. I mean that it's not simply a pointer to static code; there is an associated data structure.
Other comments are saying non-capturing closures are not closures. If we want to have this pedantic argument of definitions: proto_lambda is actually right, with Rust's definition of closures.

According to the Rust reference:

> Closure types > > A closure expression produces a closure value with a unique, anonymous type that cannot be written out.

https://doc.rust-lang.org/reference/types/closure.html

Even a non-capturing closure is written using a closure expression and produces a unique, anonymous type.

Isn't the distinguishing feature of a closure that it can capture stuff from the environment?

> Unlike a plain function, a closure allows the function to access those captured variables through the closure's copies of their values or references, even when the function is invoked outside their scope.

> The term closure is often used as a synonym for anonymous function, though strictly, an anonymous function is a function literal without a name, while a closure is an instance of a function, a value, whose non-local variables have been bound either to values or to storage locations (depending on the language; see the lexical environment section below).

My understanding is that your use of 'capture' matches up with the the use of 'bound' in the description above.

https://en.wikipedia.org/wiki/Closure_(computer_programming)

It can capture things, OP's example does not capture anything.
people casually using the term closure for anonymous functions has caused so much confusion over the years lol
If it doesn't capture anything, then it's not a closure.
There’s so much confusion out there due to people throwing out the term “closure” imprecisely, ugh