This is the closest I've been able to get. Note that it doesn't accept
stack closures. This is because ~fn doesn't seem to want to accept
non-static lifetime bounds, and potentially other issues with aliasing
stack closures. The closure story in Rust is supposed to be changing at
some point, though, so I don't know what this will eventually look like.
"""
use std::util::id;
fn ntimes(f: extern "Rust" fn(int) -> int, n: int) -> ~fn:(int) -> int {
match n {
0 => do id::<~fn:(int) -> int> |x| { x },
_ => do id::<~fn:(int) -> int> |x|
{
let nf = ntimes(f, n - 1);
nf(f(x))
},
}
}
fn double(a: int) -> int {
a * 2
}
fn main() {
let quadruple = ntimes(double, 2);
println(format!("quad = {:d}", quadruple(2)));
}
"""
On Sun, Oct 27, 2013 at 1:00 PM, Ramakrishnan Muthukrishnan <
[email protected]> wrote:
> On Sun, Oct 27, 2013 at 10:11 PM, Patrick Walton <[email protected]>
> wrote:
> > On 10/27/13 5:15 AM, Ramakrishnan Muthukrishnan wrote:
> >>
> >> I am having a hard time trying to figure out what is going on here.
> >>
> >> fn ntimes(f: &fn(int) -> int, n: int) -> &fn(int) -> int {
> >> match n {
> >> 0 => &|x| { x },
> >> _ => &|x| { f(x) },
> >> _ => &|x|
> >> {
> >> let nf = ntimes(f, n - 1);
> >> nf(f(x))
> >> },
> >> }
> >> }
> >
> >
> > The compiler is actually (admittedly obliquely) telling you about a
> memory
> > safety problem. Consider this line:
> >
> >
> >> _ => &|x| { f(x) },
>
> The '_' is a bug there, which creeped in while I was fiddling with it.
> Sorry about that. This is the function I am looking at:
>
> fn ntimes(f: &fn(int) -> int, n: int) -> &fn(int) -> int {
> match n {
> 0 => &|x| { x },
> _ => &|x|
> {
> let nf = ntimes(f, n - 1);
> nf(f(x))
> },
> }
> }
>
> > Here you're referring to the outer variable (argument in this case) `f`.
> But
> > by the time the closure is invoked, `f` won't exist, because the
> activation
> > record for the `ntimes` function won't exist anymore. It's the same
> problem
> > that occurs when you return a pointer to an argument in C. In Rust the
> > lifetime system prevents such errors, and that's what you're seeing.
>
> Very very nice! Thank you. I now understand what is going on.
>
> > Other languages get around this by moving `f` to a garbage collected box
> > implicitly, but that's contrary to the design of Rust, which has no GC
> > unless you explicitly opt in.
> >
> > From the code snippet I'm not sure exactly what you're trying to do, so I
> > don't know the most idiomatic way to solve this.
>
> `ntimes' is trying to return a closure which when invoked with an
> integer argument x will will apply the function f, n times on it. Does
> that explain it better?
>
> Thanks again. I had been reading your web pages to understand a lot of
> design decisions behind Rust. Thanks. :)
>
> --
> Ramakrishnan
> _______________________________________________
> Rust-dev mailing list
> [email protected]
> https://mail.mozilla.org/listinfo/rust-dev
>
_______________________________________________
Rust-dev mailing list
[email protected]
https://mail.mozilla.org/listinfo/rust-dev