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

Reply via email to