      (channel/chan buf xf exh))))
 
 (defn put!
+  "Schedules a put operation on the channel. Returns a promise
+  instance that will resolve to: false if channel is closed, true if
+  put is succeed. If channel has buffer, it will return immediatelly
+  with resolved promise."
   [port val]
   (let [d (p/deferred)]
     (pt/-put! port val (channel/promise->handler d))
     d))
 
 (defn take!
+  "Schedules a take operation on the channel. Returns a promise
+  instance that will resolve to: nil if channel is closed, obj if
+  value is found. If channel has non-empty buffer the take operation
+  will succeed immediatelly with resolved promise."
   [port]
   (let [d (p/deferred)]
     (pt/-take! port (channel/promise->handler d))
     d))
 
 (defn >!
-  "Perform a blocking put operation on the channel."
+  "Perform a blocking put operation with optional timeout
+  handling. Analogous to @(put! port val)."
   ([port val]
    (-> (put! port val)
        (deref)))

     (deref (p/finally d (fn [_ _] (p/cancel! t)))))))

(defn alts!
  [ports & {:keys [priority]}]
  (let [ret     (p/deferred)
        lock    (channel/promise->handler ret)

   [promesa.protocols :as pt]))

(defmacro go
  "Schedules the body to be executed asychronously, potentially using
  virtual thread if available (a normal thread will be used in other
  case). Returns a promise instance that resolves with the return
  value when the asynchronous block finishes."
  [& body]
  `(->> (px/wrap-bindings (fn [] ~@body))
        (p/thread-call channel/*executor*)))

(defmacro go-loop
  "A convencience helper macro that combines go + loop."
  [bindings & body]
  `(go (loop ~bindings ~@body)))

(defn chan
  "Creates a new channel instance, it optionally accepts buffer,
  transducer and error handler."
  ([] (chan nil nil nil))
  ([buf] (chan buf nil nil))
  ([buf xf] (chan buf xf nil))
