diff --git a/src/libcore/core.rc b/src/libcore/core.rc
index 181e54a95a4..868762a090f 100644
--- a/src/libcore/core.rc
+++ b/src/libcore/core.rc
@@ -80,9 +80,12 @@ mod math;
mod cmath;
mod sys;
mod unsafe;
+mod logging;
+
+// Concurrency
mod comm;
mod task;
-mod logging;
+mod future;
// Compiler support modules
diff --git a/src/libcore/future.rs b/src/libcore/future.rs
new file mode 100644
index 00000000000..ae90b903518
--- /dev/null
+++ b/src/libcore/future.rs
@@ -0,0 +1,153 @@
+#[doc = "
+
+A type representing values that may be computed concurrently and
+operations for working with them.
+
+Example:
+
+> let delayed_fib = future::spawn {|| fib(5000) };
+> make_a_sandwitch();
+> io::println(#fmt(\"fib(5000) = %?\", delayed_fib.get()))
+
+"];
+
+export future;
+export future::{};
+export from_value;
+export from_port;
+export get;
+export with;
+export spawn;
+
+import either = either::t;
+
+#[doc = "The future type"]
+enum future = {
+ mutable v: either<@A, comm::port>
+};
+
+#[doc = "Methods on the `future` type"]
+impl future for future {
+
+ fn get() -> A {
+ #[doc = "Get the value of the future"];
+
+ get(self)
+ }
+
+ fn with(blk: fn(A) -> B) -> B {
+ #[doc = "Work with the value without copying it"];
+
+ with(self, blk)
+ }
+}
+
+fn from_value(+val: A) -> future {
+ #[doc = "
+
+ Create a future from a value. The value is immediately available
+ and calling `get` later will not block.
+
+ "];
+
+ future({
+ mutable v: either::left(@val)
+ })
+}
+
+fn from_port(-port: comm::port) -> future {
+ #[doc = "
+
+ Create a future from a port. The first time that the value is
+ requested the task will block waiting for the result to be
+ received on the port.
+
+ "];
+
+ future({
+ mutable v: either::right(port)
+ })
+}
+
+fn get(future: future) -> A {
+ #[doc = "Get the value of the future"];
+
+ with(future) {|v| v }
+}
+
+fn with(future: future, blk: fn(A) -> B) -> B {
+ #[doc = "Work with the value without copying it"];
+
+ let v = alt future.v {
+ either::left(v) { v }
+ either::right(po) {
+ let v = @comm::recv(po);
+ future.v = either::left(v);
+ v
+ }
+ };
+ blk(*v)
+}
+
+fn spawn(+blk: fn~() -> A) -> future {
+ #[doc = "
+
+ Create a future from a unique closure. The closure will be run
+ in a new task and its result used as the value of the future.
+
+ "];
+
+ let po = comm::port();
+ let ch = comm::chan(po);
+ task::spawn {||
+ comm::send(ch, blk())
+ };
+ from_port(po)
+}
+
+#[test]
+fn test_from_value() {
+ let f = from_value("snail");
+ assert get(f) == "snail";
+}
+
+#[test]
+fn test_from_port() {
+ let po = comm::port();
+ let ch = comm::chan(po);
+ comm::send(ch, "whale");
+ let f = from_port(po);
+ assert get(f) == "whale";
+}
+
+#[test]
+fn test_iface_get() {
+ let f = from_value("fail");
+ assert f.get() == "fail";
+}
+
+#[test]
+fn test_with() {
+ let f = from_value("nail");
+ assert with(f) {|v| v} == "nail";
+}
+
+#[test]
+fn test_iface_with() {
+ let f = from_value("kale");
+ assert f.with {|v| v} == "kale";
+}
+
+#[test]
+fn test_spawn() {
+ let f = spawn {|| "bale" };
+ assert get(f) == "bale";
+}
+
+#[test]
+#[should_fail]
+#[ignore(cfg(target_os = "win32"))]
+fn test_futurefail() {
+ let f = spawn {|| fail };
+ let _x: str = get(f);
+}
\ No newline at end of file