Closed Rafagd closed 6 years ago
If this Rust function is being called from Ketos code, it would be best to use the same context for subsequent executions. Perhaps a Rust closure could carry a reference to or a clone of the context.
However, if this isn't possible, you can create a new execution context (using a Scope
, which can be extracted from the Lambda
struct's weak reference).
Ok, so here is a minimal example of what I'm doing. I would love to get rid of INTERP, even if that means ketos_fn! adding the scope as the first argument.
#[macro_use]
extern crate ketos;
static mut INTERP: *mut ketos::Interpreter = { 0 as *mut _ };
fn repeat(n: usize, lambda: &ketos::Value) -> Result<(), ketos::Error>
{
for i in 0..n {
let _ = unsafe { (*INTERP).call_value(lambda.clone(), vec![ i.into() ])? };
}
Ok(())
}
fn main ()
{
let mut interp = ketos::Interpreter::new();
unsafe {
INTERP = &mut interp as *mut _
};
ketos_fn! {
interp.scope() => "rp" =>
fn repeat(n: usize, lambda: &ketos::Value) -> ()
}
interp.run_code("(rp 1000 (lambda (i) (println \"~a\" i)))", None).unwrap();
}
One alternative would be, rather than using ketos_fn!
to create a callable Ketos value, to use Value::new_foreign_fn
to wrap a function with the signature fn(&Context, &mut [Value]) -> Result<(), Error>
.
You can then use the macro ketos_args!
to get (usize, &Value)
from the argument slice and execute the given value using the passed &Context
.
So I have this function in rust bound to ketos that receives a lambda as an argument and calls the lambda in a loop with a different value for its arguments on every run.
Sounds simple enough, but my function can't receive the context as a parameter, so I'm stuck using the interpreter as a global variable.
I understand that functional languages are not supposed to care about the context, but all functions I've found to execute the lambda require me to send the context as a parameter.
What should I do?