How can I remove the left recursions in the following grammar?
S -> “url” “(“ STRING “)” // basic services
| S “?” S // sequential execution
| S “|” S // concurrent execution
| “timeout” “(“ REAL “,” S “)” // timeout combinator
| “repeat” “(“ S “)” // repetition
| “stall” // nontermination
| “fail” // failure
The trick is to create a parent production that is right recursive.
T -> S
T -> S "?" T // sequential execution
T -> S "|" T // concurrent execution
S -> “url” “(“ STRING “)” // basic services
| “timeout” “(“ REAL “,” S “)” // timeout combinator
| “repeat” “(“ S “)” // repetition
| “stall” // nontermination
| “fail” // failure
This will recognize the same set of inputs, but beware that T is now right associative, not left associative.
Related
I want to repeat a certain user-provided function multiple times in an async context. Thus, I thought about a non-async closure that produces futures which can be consumed/awaited.
A minimal reproducible example is the following:
let counter = Arc::new(AtomicU64::new(0));
let counter_closure = counter.clone();
let future_producer = move || async {
counter_closure.fetch_add(1, Ordering::SeqCst);
};
but this results in this error
562 | let future_producer = move || async {
| _______________________________-------_^
| | | |
| | | return type of closure `impl Future<Output = ()>` contains a lifetime `'2`
| | lifetime `'1` represents this closure's body
563 | | counter_closure.fetch_add(1, Ordering::SeqCst);
564 | | };
| |_________^ returning this value requires that `'1` must outlive `'2`
How can I solve this problem?
The problem is that the closure owns counter_closure but the futures returned by the closure only reference this value owned by the closure. The signature of closures doesn't have a way to express this. It's akin to the "owning iterator" problem -- like how the Iterator trait doesn't permit expression of the case where the iterator dispenses references tied to its own lifetime, the family of closure traits that can be invoked on a reference to a closure (Fn and FnMut) don't have a way to express that the value returned from the closure borrows from the closure itself.
If the compiler permitted this to compile, it would be possible to create a use-after-free situation by dropping the closure while futures it has previously returned still exist. This would destroy counter_closure while it's still borrowed.
You can fix this by cloning the closure-owned counter_closure on each invocation of the closure before the async block, and moving this clone into the future with async move:
let counter = Arc::new(AtomicU64::new(0));
let counter_closure = counter.clone();
let future_producer = move || {
let counter_inner = counter_closure.clone();
async move {
counter_inner.fetch_add(1, Ordering::SeqCst);
}
};
This uncouples the lifetime of the future from the closure by giving the future its own Arc.
I am trying to create a Stream using a camera with a blocking capture method. The blocking call is wrapped with blocking::unblock.
use futures::stream;
use rscam::{Camera, Config};
fn frame_stream() -> impl stream::Stream {
let mut camera = Camera::new("/dev/video0").unwrap();
camera.start(&Config {
interval: (1, 30),
resolution: (1280, 720),
format: b"H264",
..Default::default()
}).unwrap();
stream::unfold(camera, |c| async move {
let frame = blocking::unblock(|| c.capture().unwrap()).await;
Some((frame, c))
})
}
Compiling gives this error message:
error[E0373]: closure may outlive the current function, but it borrows `c`, which is owned by the current function
--> src/lib.rs:15:39
|
15 | let frame = blocking::unblock(|| c.capture().unwrap()).await;
| ^^ - `c` is borrowed here
| |
| may outlive borrowed value `c`
|
note: function requires argument type to outlive `'static`
--> src/lib.rs:15:21
|
15 | let frame = blocking::unblock(|| c.capture().unwrap()).await;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
help: to force the closure to take ownership of `c` (and any other referenced variables), use the `move` keyword
|
15 | let frame = blocking::unblock(move || c.capture().unwrap()).await;
| ++++
error[E0505]: cannot move out of `c` because it is borrowed
--> src/lib.rs:17:22
|
15 | let frame = blocking::unblock(|| c.capture().unwrap()).await;
| ------------------------------------------
| | | |
| | | borrow occurs due to use in closure
| | borrow of `c` occurs here
| argument requires that `c` is borrowed for `'static`
16 |
17 | Some((frame, c))
| ^ move out of `c` occurs here
How can I guarantee to the compiler that the reference to c taken in the closure will still be valid? I assume it will be, since execution of the closure is awaited before c is returned.
Solution
stream::unfold(camera, |c| async move {
Some(
blocking::unblock(|| {
(c.capture().unwrap(), c)
}).await
)
})
You could move the camera into the inner closure, then return it once the frame capture is complete:
stream::unfold(camera, |c| async move {
Some(blocking::unblock(|| move {
let frame = c.capture().unwrap()).await;
(frame,c)
})
})
.await does not guarantee liveness. This is the general problem of scoped async tasks. Futures can be canceled at any time. Consider:
let future = async {
let local = 123;
blocking::unblock(|| local).await;
};
// Poll `future`, but only once.
futures::block_on(async move { futures::poll!(future) });
We started a task using local data, then dropped the future. The task continues executing but the local data is gone. For this reason, there is currently no sound way to expose an async API allowing using local data similar to scoped threads. You have to use 'static data, for example by wrapping in Arc.
See also blocking issue #4.
I'm new to Elmish.Xamarin and Xamarin itself. I'm trying to build an application, using this calculator example. Main difference is that in this example UI is updated upon user input, and update function is pure and just evaluates next state of model:
let update msg model =
match msg with
| Clear -> Initial
| Digit digit ->
match model with
| Initial | Error | Result _ -> Operand (double digit)
| Operand op -> Operand (double (string op + string digit))
| OperandOperator (operand, operator) -> OperandOperatorOperand (operand, operator, double digit)
| OperandOperatorOperand (op1, operator, op2) -> OperandOperatorOperand (op1, operator, double (string op2 + string digit))
| Operator operator ->
match model with
| Initial | Error -> model
| Result operand // previously calculated result is now the first operand
| Operand operand | OperandOperator (operand, _) -> OperandOperator(operand, operator)
| OperandOperatorOperand _ -> calculate model msg
| Equals -> calculate model msg
I need a different scenario: user's input doesn't affect UI directly, instead I store user's messages and evaluate next state on schedule, so in my app's core I pass updateUI: gameState -> unit func:
let gameAgentFn (mailboxNetwork: MailboxNetwork) updateUi gameState cmd =
let timerAgent = timerAgent mailboxNetwork
match gameState.gameFrame with
| Frame field ->
let gameState = Game.updateGameState gameState cmd
timerAgent.Post Next
updateUi gameState
gameState
Problem is I can't understand, what function to pass and how to build interaction with this design, since as far as I can see, it expects me to pass pure function to evaluate next state and the rest is being done underneath.
I am writing a websocket server in Rust using rust-websocket and its Tokio-based async system. I can serve clients just fine, however, I can not figure out how to share mutable state between the clients. Here is some (partial) code demonstrating this issue:
let mut core = Core::new().unwrap();
let handle = core.handle();
let server = Server::bind("localhost:62831", &handle).unwrap();
let mut state = State{
...
};
let f = server.incoming()
.map_err(|InvalidConnection {error, ..}| error)
.for_each(|upgrade, _)| {
let f = upgrade.accept()
.and_then(|s, _| {
let ctx = ClientContext{
// some other per-client values
state: &mut state,
}
...
return s.send(Message::binary(data).into())
.and_then(move |s| Ok(s, ctx)); // this could be the complete wrong way to insert context into the stream
}).and_then(|s, ctx| {
// client handling code here
});
handle.spawn(f
.map_err(...)
.map(...)
);
return Ok(())
});
core.run(f).unwrap();
This code errors with this:
error[E0373]: closure may outlive the current function, but it borrows `**state`, which is owned by the current function
--> src/main.rs:111:27
|
111 | .and_then(|(s, _)| {
| ^^^^^^^^ may outlive borrowed value `**state`
...
114 | state: &mut state,
| ----- `**state` is borrowed here
|
help: to force the closure to take ownership of `**state` (and any other referenced variables), use the `move` keyword, as shown:
| .and_then(move |(s, _)| {
When trying the compiler's suggestion, I get this:
error[E0507]: cannot move out of captured outer variable in an `FnMut` closure
--> src/main.rs:111:27
|
111 | .and_then(move |(s, _)| {
| ^^^^^^^^^^^^^ cannot move out of captured outer variable in an `FnMut` closure
error: `state` does not live long enough
--> src/main.rs:114:37
|
114 | state: &mut state,
| ^^^^^ does not live long enough
...
122 | })
| - borrowed value only lives until here
|
= note: borrowed value must be valid for the static lifetime...
I also tried wrapping the state in a RefCell (creating the RefCell right after the state itself), however, the compiler gives a similar move error since it tries to move the RefCell into the closure that creates the client context.
You're pretty close with the RefCell. What you need now is an Rc to wrap that RefCell so you can clone the Rc and not capture the RefCell itself.
let shared_state = Rc::new(RefCell::new(State::new())));
incoming().for_each(move |s, _| {
let shared_state = shared_state.clone(); // Left uncaptured
shared_state.borrow_mut().do_mutable_state_stuff(); // Could panic
});
Note that since you're using Rc's and RefCell's now, you'll likely need to go ahead and convert your ClientContext struct to storing an Rc> instead of a &mut State. It may be possible to keep using &mut State's for some things, but your &mut State's will be tied to the lifetime of the RefMut, and if you keep it alive until the next closure runs, the borrows will panic (or fail if you use the try_ variants).
Also keep in mind if you decide you want to have multiple threads in your reactor, you will just need to change Rc to Arc, and RefCell to Mutex, which is a very natural conversion when it's needed.
I'm just starting to fork() and I'm having some difficulties understanding the parallel execution. I've found this example code and I want to know if the first time it will go true or false (I know if pid1==0 it means it's a child, etc). I also want to know how many copies (children will be created) and some details on the general execution.
I have tried to run it and added the return 0; (my original source didn't have it) just to see if exits... but as you can see it "waits"
http://i.imgur.com/D3XEFgs.png
int main(void)
{
int pid1, pid2, pid3, pid4;
pid1=fork();
if (pid1!=0)
{
pid2=fork();
pid3=fork();
printf("\t\t IF(TRUE) pid1=%d and pid2=%d and pid3=%d\n",
pid1, pid2, pid3);
}
else
{
pid4=fork();
printf("\nIF(False) FATHER is talking with pid1=%d and pid4=%d\n",
pid1, pid4);
}
return 0;
}
This program creates five descendant processes, and makes six calls to printf, of which four will be the IF(TRUE) message and two will be IF(FALSE). Here is an ASCII-art diagram of the control flow; every time it branches, both sides are executed, with the parent going straight down and the child to the right. The numbers are the fork calls initializing the pid1, pid2, ... variables, the letters T and F are the IF(TRUE) and IF(FALSE) messages, and the _ is the return 0 at the end of the function. This program does not wait for anything; all control flow paths reach the return 0 eventually.
|
1
|\------\
2 4
|\--\ |\
3 3 | |
|\ |\ | |
T T T T F F
| | | | | |
_ _ _ _ _ _
The output messages may appear in any order. And it's possible that the topmost parent process will exit (returning control to the shell) before all of the descendant processes have written their messages, so (as is visible in your screeenshot) the shell prompt may get jumbled up with the messages, too.
Note that, going by the text of the messages, you have your if conditional backward: pid1 != 0 is true in the parent, not the child.
Both true and false will be used on the first time.
fork() copies the program (creates 1 child) and both programs continue execution from that point. The child process will take one branch and the parent the other.
The number of fork()s is as follows:
You start with 1 process
After pid1 -> +1 processes
Parent Branch
After pid4 -> +1 processes
Child Branch
After pid2 -> +1 processes
BOTH of the newly created processes run fork() for pid3, so after pid3 -> +2 processes
You get 5 children + the original process.