Fork me on GitHub
#clojure
<
2024-08-04
>
lread00:08:20

I really do love babashka and assume that it is widely used. If we consider babashka a Clojure dialect, could it be added to the next Clojure survey to get a more real idea of how widely it is used? I'm not sure how to link to the survey questions, but it is "Q22. Which dialects of Clojure do you use?" in the 2023 survey I am thinking of. I'll post an image in the thread.

🤝 2
1
lread00:08:52

Would squint, cherry, and the upcoming jank be considered dialects too?

hiredman01:08:10

There is no spec for clojure, that if you implement you are "clojure". So largely the determinant is what has been blessed by rhickey, and none of those other things have been to my knowledge (but I certainly could have missed such a thing)

hiredman01:08:04

The survey being a project of core, likely only takes which rich considers to be dialects of clojure as such, and everything else is just "clojure like"

Daniel Craig02:08:10

Fennel and Yamlscript could be be considered dialects of Clojure too

Alex Miller (Clojure team)03:08:23

we've considered this in the past and opted to only list the "official" dialects, but have not made decisions about this year yet

didibus03:08:11

I'd list them all personally. It's interesting from the perspective of understanding the state of Clojure. Just seeing non official dialects have high numbers would be pretty indicative of a healthy growth around the language. I think what has proper cljc support could be a good way to draw the line.

👍 1
hiredman05:08:02

The way cljc works that is an open set, anyone can create a something clojure like, and just bind the right value when read is callled

hiredman05:08:15

It is sort of a brand dilution issue. If clojure is whatever rich says is clojure, the more things that rich has not said are clojure are considered to be clojure, the less meaningful the name clojure is

hiredman05:08:06

(sorry, features(what cljc uses to select the variant) are arguments passed to read, not a dynamic binding)

didibus07:08:07

If there actually are libraries and applications that run on Clojure and another dialect using .cljc, I would include it as a Clojure dialect. Some clojure-like don't bother at all, because they only are inspired by, while others truly are adapting Clojure to a new host and cljc is needed because of the differences from Clojure due to the nature of the new host. Completely disagree about making Clojure less meaningful. If people are adapting Clojure to new host, while keeping compatibility with it, that's brand expansion. It makes Clojure more meaningful, and in practical ways, by giving it more reach.

Alvydas Vitkauskas12:08:55

Then probably basilisp could be considered as a clojure on python host?

👍 1
lread15:08:03

Thanks, @U064X3EF3. Would a separate question make more sense? Maybe something like "Which unofficial variants of Clojure do you use?" In addition to squint, cherry, babashka, jank, and basilisp, I guess this might include shadow-cljs, and maybe even tools like Planck?

👍 1
phill16:08:15

I hope there will be a way to track the uptake of ClojureDart on the same axes as Clojure, ClojureScript, and ClojureCLR.

clojuredart 2
lread16:08:04

Oh yeah, ClojureDart! An important omission on my part!

miwal11:08:06

Is it possible to write a guide on how to understand java error messages from the perspective of clojure? If the answer is yes, does such a guide exist? Example, I think the below just means "I was expecting a function, but you gave me an object". HTTP ERROR 500 java.lang.ClassCastException: class reitit.core$single_static_path_router$reify__2175 cannot be cast to class clojure.lang.IFn (reitit.core$single_static_path_router$reify__2175 is in unnamed module of loader clojure.lang.DynamicClassLoader @5c8d58ed; clojure.lang.IFn is in unnamed module of loader 'app')

Ben Sless11:08:34

You passed a reitit router as a handler in some place and the compiler emitted code that tried and failed to invoke it as a function (IFn)

miwal11:08:07

yes, i intentionally caused the error in this case :)

Ben Sless12:08:40

okay, I see, these guides do exist, btw

shaunlebron18:08:11

a job for LLMs?

exitsandman06:08:26

thrown together in a hurry:

(ns mini.playground
  (:require [clojure.data.json :as json]
            [clojure.datafy :as datafy]
            [clj-http.client]
            [clojure.spec.alpha :as spec]
            [mini.playground.headers :as-alias headers]
            [mini.playground.options :as-alias options]))

(defn ask-groq
  ([token model prelude]
   (ask-groq token model prelude {}))
  ([token model prelude {:as opts}]
   (json/read-str
    (:body
     (clj-http.client/request
      {:method "POST"
       :url ""
       :insecure? true
       :headers {"Authorization" (str "Bearer " token)
                 "Content-Type" "application/json"}
       :body
       (json/write-str
        (merge (into {} (keep #(let [k (key %)]
                                 (when (and (keyword? k) (= (namespace ::options/ns) (namespace k)))
                                   (update % 0 name))))
                     opts)
               {:model model
                :messages (mapv #(do {:role "user" :content %})
                                (cond-> prelude (string? prelude) vector))}))})))))

(defn first-response
  [groq-answer]
  (get-in groq-answer ["choices" 0 "message" "content"]))

(defn maybe-var-invocation
  [x]
  (when (seq? x)
    (let [f (first x)]
      (when (symbol? f)
        f))))

(defn spresolve
  [s]
  (if (special-symbol? s)
    s
    (resolve s)))

(defn maybe-symbolic-invocation
  [x]
  (when (seq? x)
    (let [f (first x)]
      (when (symbol? f)
        (spresolve f)))))

(spec/def ::normal-code
  #(not (`#{finally catch} (maybe-symbolic-invocation %))))

(spec/def ::finally
  #(= `finally (maybe-symbolic-invocation %)))

(spec/def ::try-explained-body
  (spec/cat
   :body (spec/+ ::normal-code)
   :finally?? (spec/? ::finally)))

(defn conform-or-throw
  [spec val]
  (let [conformed (spec/conform spec val)]
    (if-not (spec/invalid? conformed)
      conformed
      (throw (ex-info "failed conforming:"
                      {:value val
                       :spec (spec/describe spec)
                       :explanation (spec/explain-str spec val)})))))

(defmacro with-llm-explanation
  [base & stuff-then-maybe-finally]
  (let [{:keys [:body :finally??]}
        (conform-or-throw ::try-explained-body stuff-then-maybe-finally)] 
     `(try (do ~@body)
           (catch ~base e#
             (throw
              (ex-info
               "let the bots explain this!"
               {:explanation
                (first-response
                 (ask-groq
                  "####"
                  "llama3-8b-8192"
                  ["Here's the erroring code"
                   (pr-str (quote (do ~@body)))
                   "and here's the datafied Clojure exception."
                   (pr-str (datafy/datafy e#))
                   "Explain the error and where it may have happened. Be brief."]))}
               e#)))
           ~@(when finally?? [finally??]))))

(defn make-ndarr [shape fill]
  (throw (ex-info "negative values in ndarray shape" {:shape [-1 12]})))

(comment
  (with-llm-explanation Exception
    (try (make-ndarr [-1 12] 0)
         (catch Exception e (throw (Exception. "whoops!" e)))))
  )