This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2024-01-10
Channels
- # announcements (14)
- # beginners (55)
- # calva (4)
- # cider (9)
- # clojure (56)
- # clojure-austin (25)
- # clojure-brasil (1)
- # clojure-dev (29)
- # clojure-europe (44)
- # clojure-mexico (1)
- # clojure-nl (2)
- # clojure-norway (1)
- # clojure-uk (5)
- # clojurescript (15)
- # cursive (9)
- # datomic (5)
- # emacs (30)
- # events (1)
- # graalvm (30)
- # honeysql (17)
- # hyperfiddle (54)
- # introduce-yourself (1)
- # jobs-discuss (6)
- # kaocha (2)
- # leiningen (5)
- # lsp (6)
- # malli (3)
- # missionary (16)
- # off-topic (42)
- # overtone (40)
- # pedestal (2)
- # re-frame (21)
- # shadow-cljs (16)
- # squint (2)
- # tools-deps (14)
easiest way is a case
statement, if you search for "routing" there are several discussions
we have a hyperfiddle.router
coming for complex route compositions but it's not ready
core.match
also works
I learned how to do it from this example: https://github.com/jeans11/demo-rama-electric/blob/main/bases/web-ui/src/dre/web_ui/routes.cljc (reitit frontend based)
Hi, You can use that template: https://github.com/Bariscanates404/param-routing-electric-datomic-template History router
@dustingetz Is Electric uniquely possible in Clojure, or would it work in any language that has macros, like Rust or Swift?
Strictly speaking, maybe possible. Macros not strictly needed, the compiler can be language-external (i.e. Babel). Immutability-by-default is important to the reactive dataflow semantics. Mutation tracking (for imperative langs such as JS or WASM) is a hard unsolved problem, only beginning to be tackled in the literature i've seen. So technology is not there yet. More loosely speaking, perhaps a 65% good enough solution could get adoption in mainstream, but you'd still need a modern concurrency library and there's nothing good enough in JS that I've seen (we use Missionary which is the state of art, years ahead of effect-ts)
Clojure is the right place to do an experiment like this and be able to move reasonably quickly, and in a commercial setting with PL enthusiasts to early adopt and talk to us while we figure out the design, etc
this is kinda tough to describe, but i will attempt it anyhow:
there is s1
, s2
, s3
, ... and these are coming in at different times sequentially.
i want to stream (in the ui) s1
, s2
, and s3
one character at a time, but stream in s2
only after s1
, s3
only after s2
, etc.
so if s1 = "hello"
and s2 = "there"
, then the user would see h
, he
, hel
, hell
, hello
, then once s2 is received, hellot
, helloth
, etc.
this is what i have currently, which doesn't do any accumulation
(let [!q (atom "htht")
q (e/watch !q)]
(letfn [(random-delayed-seed [fixed-delay variable-delay xs]
(m/ap
(m/?
(let [x (m/?> (m/seed xs))]
;; order matters here
(m/sleep
(+ fixed-delay (rand-int variable-delay))
x)))))]
(when-some [x
(->> q
(random-delayed-seed 50 150)
(m/reductions str "")
new)]
(js/console.log x)
(div (text x))))
(div (text q))
(dom/input
(dom/on "keydown"
(e/fn [e]
(when (= "Enter" (.-key e))
(reset! !q (.. e -target -value)))))))
josh this is really interesting what's your desired outcome? trickle-write of any streamed input in any asynchronous order received?
is there a good reason the llm would give you a strange output sequence ? or is that more of a design consideration.
how do we know the appropriate sequence of stuff? is everything tagged with a sequence number on the way in?
Oh okay, they are coming in in the correct sequence already, gotcha. I reckon putting it on a channel is the right answer
i am assuming just reset! of atom is not enough because it'll completely forget about previous values
told chatGPT4 to generate an example with put and take, does it look right ?
(ns your-namespace
(:require [clojure.core.async :refer [chan put! take! go]]
[cljs-http.client :as http]))
(defn get-llm-response [request]
;; Function to get a response from the LLM (simulated here as an HTTP request)
;; In a real scenario, you would replace this with an actual HTTP request to the LLM API
(http/get ""
{:params {:query request}}))
(defn process-llm-response [response]
;; Function to process the response from the LLM
(println "Received response from LLM:" response))
(defn send-request-to-llm [request channel]
;; Function to send a request to the LLM and put the response into the channel
(go (let [response (<! (get-llm-response request))]
(put! channel response))))
(defn main []
;; Main function to demonstrate put! and take!
(let [channel (chan)] ; Create a new channel
;; Send a request to the LLM
(send-request-to-llm "Hello LLM" channel)
;; Take the response from the channel and process it
(go (let [response (<! channel)]
(process-llm-response response)))))
(main)
can't quite figure it out...
(let [!q (atom "htonuehto")
q (e/watch !q)
ch (a/chan)]
(div (text ch))
(letfn [(random-delayed-seed [fixed-delay variable-delay xs]
(m/ap
(m/?
(let [x (m/?> (m/seed (m/?> xs)))]
(m/sleep
(+ 20 (rand-int 200))
x)))))]
(when-some [x
(->> (channel-flow ch)
(random-delayed-seed 50 150)
(m/reductions str "")
new)]
(js/console.log x)
(div (text x))))
(div (text q))
(dom/input
(dom/on "keydown"
(e/fn [e]
(when (= "Enter" (.-key e))
(a/put! ch (.. e -target -value)))))))
this code
(defn forever [task]
(m/ap (m/? (m/?> (m/seed (repeat task))))))
(defn- take! [chan]
(m/via
m/blk
(let [r (a/<!! chan)]
(if (nil? r)
(throw (ex-info "take cancelled, channel closed" {:cancelled? true}))
r))))
(defn channel-flow [ch-recv]
(forever (take! ch-recv)))
whatever it is, i keep getting
#object[Error Error: Unsupported operation.] core.cljs:200:23
@U09FL65DK i am noticing difference in behavior between those two