1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
//! Allocate it where?
//!
//!   - **Date:** November 8, 2015
//!   - **Subject:** Returning functions from other functions, and thinking
//!     about the stack, the heap, and reference types.
//!   - [**Audio**][mp3]
//!
//! [mp3]: https://www.podtrac.com/pts/redirect.mp3/cdn.newrustacean.com/file/newrustacean/e005.mp3
//!
//! <audio style="width: 100%" title="Allocate it where?" controls preload=metadata src="https://www.podtrac.com/pts/redirect.mp3/cdn.newrustacean.com/file/newrustacean/e005.mp3" />
//!
//! # Notes
//!
//! This episode, we look at returning functions from other functions, and as
//! part of that discuss some basics about the stack and the heap---and why we
//! need to care about them for returning functions.
//!
//! The functions themselves are not especially interesting; they just show you
//! the basic form you use to return functions from other functions, and how to
//! then use them in another function. You'll want to take a detailed look
//! instead at the documentation for each (or just read the [source][notes-1]!),
//! because that's where the meat of the discussion in this week's code is.
//!
//! ## Corrigenda
//!
//!   - Steve Klabnik [pointed out][notes-2] that my description of `Vector`
//!     types as totally heap-allocated was misleading. It's better to say that
//!     the *contents* of the `Vector` -- its data -- is heap-allocated, while
//!     the memory for the smart pointer and associated metadata are allocated
//!     on the stack. I had this in mind, and sort of alluded to it earlier in
//!     the discussion, but the way I actually said it was misleading at best.
//!
//!   - Chad Sharp (@crossroads1112 on GitHub) [clarified][notes-3] that in C99,
//!     C *does* support dynamic array allocation, though it became optional for
//!     compilers to implement it as of C11. I forgot about this because I spend
//!     so much of my time dealing with Visual C++, which does not support
//!     dynamic array allocation. (Notably, Visual C does; it is Visual C++
//!     which does not: remember, C and C++ are related but distinct languages.)
//!
//! Thanks to Steve and Chad for their helpful feedback!
//!
//! [notes-1]: /src/show_notes/e005.rs.html
//! [notes-2]: https://users.rust-lang.org/t/new-rustacean-podcast-e005-allocate-it-where-2015-11-08/3153/13?u=chriskrycho
//! [notes-3]: https://github.com/chriskrycho/newrustacean.com/issues/7
//!
//! # Links
//!
//!   - [Rust 1.4 release announcement][links-1]
//!   - ["Clarify (and improve) rules for projections and well-formedness"][links-2]
//!   - [MSVC support tracking issue][links-3]
//!   - [Rust 1.4 full release notes][links-4]
//!   - ["What and where are the stack and the heap?"][links-5]
//!
//! [links-1]: http://blog.rust-lang.org/2015/10/29/Rust-1.4.html
//! [links-2]: https://github.com/rust-lang/rfcs/blob/master/text/1214-projections-lifetimes-and-wf.md
//! [links-3]: https://github.com/rust-lang/rfcs/issues/1061
//! [links-4]: https://github.com/brson/rust/blob/relnotes/RELEASES.md
//! [links-5]: http://stackoverflow.com/questions/79923/what-and-where-are-the-stack-and-heap
//!
//! # Sponsors
//!
//!   - reddraggone9
//!   - [Chris Patti][sponsors-1]
//!
//! [sponsors-1]: http://podcastinit.com
//!
//! ## Become a sponsor
//!
//!   - <a href="https://www.patreon.com/newrustacean" rel="payment">Patreon</a>
//!   - [Venmo](https://venmo.com/chriskrycho)
//!   - [Dwolla](https://www.dwolla.com/hub/chriskrycho)
//!   - [Cash.me](https://cash.me/$chriskrycho)
//!
//! # Follow
//!
//!   - New Rustacean:
//!     + Twitter: [@newrustacean](https://www.twitter.com/newrustacean)
//!       + App.net: [@newrustacean](https://alpha.app.net/newrustacean)
//!     + Email: [hello@newrustacean.com](mailto:hello@newrustacean.com)
//!   - Chris Krycho
//!     + Twitter: [@chriskrycho](https://www.twitter.com/chriskrycho)
//!       + App.net: [@chriskrycho](https://alpha.app.net/chriskrycho)

/// Creates a function which doubles an integer.
///
/// Note that it doesn't have `Fn(i32) -> i32` as its return type, but rather
/// `Box<Fn(i32) -> i32`. At present, functions have to be explicitly
/// heap-allocated. If we tried to return just a `Fn` type, we'd end up in a
/// tangled mess of lifetime and ownership (whether with a regular function, as
/// here, or a closure as in `doubler_closure_factory`).
pub fn doubler_factory() -> Box<dyn Fn(i32) -> i32> {
    /// The doubler function we will return.
    fn double(n: i32) -> i32 {
        n * 2
    }
    Box::new(double)
}

/// Creates a closure which doubles an integer.
///
/// Compare with the function above: this is basically identical to
/// `doubler_factory`, the only difference being that in this case, we return a
/// closure rather than a standalone function. That has substantial
/// ramifications for using closures and named functions, of course; refer to
/// the discussion in [e004][e004] for details
///
/// [e004]: /show_notes/e004/
pub fn doubler_closure_factory() -> Box<dyn Fn(i32) -> i32> {
    // We could also write this as `Box::new(|n| n * 2)`, of course.
    let doubler = |n| n * 2;
    Box::new(doubler)
}

/// Uses the `doubler_factory` to get a function which doubles a number.
///
/// By contrast, here's a function which simply won't compile:
///
/// ```rust,ignore
/// fn will_not_compile() -> Fn(i32) {
///     let a_closure = |n| println!("Seriously. This won't compile. {}", n);
///     a_closure
/// }
/// ```
///
/// And another. This gets us a bit closer, because you actually have both a
/// concrete reference type and a lifetime. However, it still won't compile,
/// because after `get_normal_function_with_lifetime` ends, the function goes
/// out of scope and the reference points to junk value.
///
/// ```rust,ignore
/// fn get_normal_function_with_lifetime() -> &'static (Fn(i32) -> i32) {
///     fn multiply_by_3(n: i32) -> i32 {
///         n * 3
///     }
///
///     return &multiply_by_3;
/// }
/// ```
///
/// Even this approach doesn't work, because although the *function* lives on
/// past the end of the `get_normal_external_fn_with_lifetime`, the reference
/// created during that function call *doesn't*.
///
/// ```rust,ignore
/// fn multiply_by_4(n: i32) -> i32 { n * 4 }
///
/// fn get_normal_external_fn_with_lifetime() -> &'static (Fn(i32) -> i32) {
///     &multiply_by_4
/// }
/// ```
///
/// The solution, as we saw at the beginning, is to use `Box::new` to
/// heap-allocate the function result instead.
pub fn demonstrate_function_returns() {
    let double = doubler_factory();
    println!("{:}", double(14));
}