diff --git a/exemples/coroutines_better/Cargo.lock b/exemples/coroutines_better/Cargo.lock
new file mode 100644
index 0000000000000000000000000000000000000000..426d5edea5ad8a854b57bc0ff026682ee3f0151d
--- /dev/null
+++ b/exemples/coroutines_better/Cargo.lock
@@ -0,0 +1,113 @@
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+version = 3
+
+[[package]]
+name = "coroutines_better"
+version = "0.1.0"
+dependencies = [
+ "mio",
+]
+
+[[package]]
+name = "libc"
+version = "0.2.171"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c19937216e9d3aa9956d9bb8dfc0b0c8beb6058fc4f7a4dc4d850edf86a237d6"
+
+[[package]]
+name = "log"
+version = "0.4.26"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "30bde2b3dc3671ae49d8e2e9f044c7c005836e7a023ee57cffa25ab82764bb9e"
+
+[[package]]
+name = "mio"
+version = "1.0.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2886843bf800fba2e3377cff24abf6379b4c4d5c6681eaf9ea5b0d15090450bd"
+dependencies = [
+ "libc",
+ "log",
+ "wasi",
+ "windows-sys",
+]
+
+[[package]]
+name = "wasi"
+version = "0.11.0+wasi-snapshot-preview1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
+
+[[package]]
+name = "windows-sys"
+version = "0.52.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
+dependencies = [
+ "windows-targets",
+]
+
+[[package]]
+name = "windows-targets"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973"
+dependencies = [
+ "windows_aarch64_gnullvm",
+ "windows_aarch64_msvc",
+ "windows_i686_gnu",
+ "windows_i686_gnullvm",
+ "windows_i686_msvc",
+ "windows_x86_64_gnu",
+ "windows_x86_64_gnullvm",
+ "windows_x86_64_msvc",
+]
+
+[[package]]
+name = "windows_aarch64_gnullvm"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
+
+[[package]]
+name = "windows_aarch64_msvc"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
+
+[[package]]
+name = "windows_i686_gnu"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b"
+
+[[package]]
+name = "windows_i686_gnullvm"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
+
+[[package]]
+name = "windows_i686_msvc"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
+
+[[package]]
+name = "windows_x86_64_gnu"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
+
+[[package]]
+name = "windows_x86_64_gnullvm"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
+
+[[package]]
+name = "windows_x86_64_msvc"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
diff --git a/exemples/coroutines_better/Cargo.toml b/exemples/coroutines_better/Cargo.toml
new file mode 100644
index 0000000000000000000000000000000000000000..8318b4d300019db0845503d46a6eb36e62845bf1
--- /dev/null
+++ b/exemples/coroutines_better/Cargo.toml
@@ -0,0 +1,7 @@
+[package]
+name = "coroutines_better"
+version = "0.1.0"
+edition = "2021"
+
+[dependencies]
+mio = { version = "1.0.3", features = ["net", "os-poll"] }
diff --git a/exemples/coroutines_better/src/future.rs b/exemples/coroutines_better/src/future.rs
new file mode 100644
index 0000000000000000000000000000000000000000..40ec06d25678af28fdae86160f9d8a972a2b2da5
--- /dev/null
+++ b/exemples/coroutines_better/src/future.rs
@@ -0,0 +1,20 @@
+// Future trait looks like standard Future except for the missing context
+// pub trait Future {
+//    type Output;
+//    fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output>;
+//}
+pub trait Future {
+    type Output;
+
+    fn poll(&mut self) -> PollState<Self::Output>;
+}
+
+// Similar to the Poll #[derive(Debug)]
+// pub enum Poll<T> {
+//     Ready(T),
+//     Pending,
+// }
+pub enum PollState<T> {
+    Ready(T),
+    NotReady,
+}
diff --git a/exemples/coroutines_better/src/http.rs b/exemples/coroutines_better/src/http.rs
new file mode 100644
index 0000000000000000000000000000000000000000..77372b2ab20064fc33ef1f39dc7429ebae3e326a
--- /dev/null
+++ b/exemples/coroutines_better/src/http.rs
@@ -0,0 +1,80 @@
+use mio::{Interest, Token};
+
+use crate::future::{Future, PollState};
+use crate::runtime;
+use std::io::{ErrorKind, Read, Write};
+
+fn get_req(path: &str) -> String {
+    format!(
+        "GET {path} HTTP/1.1\r\n\
+        Host: localhost\r\n\
+        Connection: close\r\n\
+        \r\n"
+    )
+}
+
+pub struct Http;
+
+impl Http {
+    pub fn get(path: &str) -> impl Future<Output = String> {
+        HttpGetFuture::new(path)
+    }
+}
+
+struct HttpGetFuture {
+    stream: Option<mio::net::TcpStream>,
+    buffer: Vec<u8>,
+    path: String,
+}
+
+impl HttpGetFuture {
+    fn new(path: &str) -> Self {
+        Self {
+            stream: None,
+            buffer: vec![],
+            path: String::from(path),
+        }
+    }
+
+    fn write_request(&mut self) {
+        let stream = std::net::TcpStream::connect("localhost:8080").unwrap();
+        stream.set_nonblocking(true).unwrap();
+        let mut stream = mio::net::TcpStream::from_std(stream);
+        stream.write_all(get_req(&self.path).as_bytes()).unwrap();
+        self.stream = Some(stream);
+    }
+}
+
+impl Future for HttpGetFuture {
+    type Output = String;
+
+    fn poll(&mut self) -> PollState<Self::Output> {
+        if self.stream.is_none() {
+            println!("First poll - start operation");
+            self.write_request();
+            // 1. Registering the Tcp stream as a source of events in the poll instance
+            // 2. On retourne pas encore NotReady mais on essaie de lire le stream directement
+        }
+        let mut buf = vec![0u8; 4096];
+        loop {
+            match self.stream.as_mut().unwrap().read(&mut buf) {
+                Ok(0) => {
+                    let s = String::from_utf8_lossy(&self.buffer);
+                    break PollState::Ready(String::from(s));
+                }
+                Ok(n) => {
+                    self.buffer.extend(&buf[0..n]);
+                    continue;
+                }
+                Err(e) if e.kind() == ErrorKind::WouldBlock => {
+                    println!("Data not ready");
+                    break PollState::NotReady;
+                }
+                Err(e) if e.kind() == ErrorKind::Interrupted => {
+                    continue;
+                }
+                Err(e) => panic!("{e:?}"),
+            }
+        }
+    }
+}
diff --git a/exemples/coroutines_better/src/main.rs b/exemples/coroutines_better/src/main.rs
new file mode 100644
index 0000000000000000000000000000000000000000..ac1fdc2670df8ace39aa641968d10e50a8a06a9f
--- /dev/null
+++ b/exemples/coroutines_better/src/main.rs
@@ -0,0 +1,87 @@
+mod future;
+mod http;
+mod runtime;
+
+use future::{Future, PollState};
+use http::Http;
+use runtime::Runtime;
+
+fn main() {
+    let future = async_main();
+    let mut runtime = Runtime::new();
+    runtime.block_on(future);
+}
+
+// =================================
+// We rewrite this:
+// =================================
+// coroutine fn async_main() -> impl Future<Output = String> {
+//     println!("Program starting");
+//     let txt = Http::get("/600/HelloAsyncAwait").wait;
+//     println!("{txt}");
+//     let txt = Http::get("/400/HelloAsyncAwait").wait;
+//     println!("{txt}");
+// }
+
+// =================================
+// Into this:
+// =================================
+
+fn async_main() -> impl Future<Output = String> {
+    Coroutine::new()
+}
+
+enum State {
+    Start,
+    Wait1(Box<dyn Future<Output = String>>),
+    Wait2(Box<dyn Future<Output = String>>),
+    Resolved,
+}
+
+struct Coroutine {
+    state: State,
+}
+
+impl Coroutine {
+    fn new() -> Self {
+        Self {
+            state: State::Start,
+        }
+    }
+}
+
+impl Future for Coroutine {
+    type Output = String;
+
+    fn poll(&mut self) -> PollState<Self::Output> {
+        loop {
+            match self.state {
+                State::Start => {
+                    println!("Program starting");
+                    let fut1 = Box::new(Http::get("/600/HelloAsyncAwait"));
+                    self.state = State::Wait1(fut1);
+                }
+
+                State::Wait1(ref mut future) => match future.poll() {
+                    PollState::Ready(txt) => {
+                        println!("{txt}");
+                        let fut2 = Box::new(Http::get("/400/HelloAsyncAwait"));
+                        self.state = State::Wait2(fut2);
+                    }
+                    PollState::NotReady => break PollState::NotReady,
+                },
+
+                State::Wait2(ref mut future) => match future.poll() {
+                    PollState::Ready(txt) => {
+                        println!("{txt}");
+                        self.state = State::Resolved;
+                        break PollState::Ready(String::new());
+                    }
+                    PollState::NotReady => break PollState::NotReady,
+                },
+
+                State::Resolved => panic!("Polled a resolved future"),
+            }
+        }
+    }
+}
diff --git a/exemples/coroutines_better/src/runtime.rs b/exemples/coroutines_better/src/runtime.rs
new file mode 100644
index 0000000000000000000000000000000000000000..88b8e7f053f232363686cb2bfe6266055d549cd8
--- /dev/null
+++ b/exemples/coroutines_better/src/runtime.rs
@@ -0,0 +1,34 @@
+use std::sync::OnceLock;
+
+use mio::{Events, Poll, Registry};
+
+use crate::future::{Future, PollState};
+
+static REGISTRY: OnceLock<Registry> = OnceLock::new();
+pub fn registry() -> &'static Registry {
+    REGISTRY.get().expect("Called outside a runtime context")
+}
+
+pub struct Runtime {
+    poll: Poll,
+}
+
+impl Runtime {
+    pub fn new() -> Self {
+        // 1. creation d'une nouvelle instance de Poll
+        // 2. try_clone() du registry associé pour pouvoir ajouter une source plus tard
+        // 3. set() le registry au REGISTRY
+        // 4. return d'une nouvelle install avec le poll associé
+        unimplemented!()
+    }
+
+    pub fn block_on<F>(&mut self, future: F)
+    where
+        F: Future<Output = String>,
+    {
+        // 1. future -> mut future
+        // 2. tant que future.poll() n'est pas Ready poll.poll() un mut Event
+        // 3. Voilà
+        unimplemented!()
+    }
+}