351
2
submitted 6 months ago by planet@clj.social to c/clojure@lemmy.ml

4 models of software development as a factory

https://ericnormand.me/article/software-factory

Agile software development came from borrowing processes and ideas from manufacturing. Is software engineering like factory work? I examine four metaphors of software engineering as a factory.

#clojure #clj #cljs !clojure@lemmy.ml @clojure

352
2
submitted 6 months ago by planet@clj.social to c/clojure@lemmy.ml

March & April 2024 Long-Term Project Updates

https://www.clojuriststogether.org/news/march-april-2024-long-term-project-updates/

Our 2024 long-term developers report on an incredible body of work for March and April. A heartfelt thanks to all! Bozhidar Batsov: CIDER Michiel Borkent: squint, neil, clj-kondo,nbb, CLI, and more Toby Crawley: clojars-web Thomas Heller:...

#clojure #clj #cljs !clojure@lemmy.ml @clojure

353
3
submitted 6 months ago by yogthos@lemmy.ml to c/clojure@lemmy.ml

I had to make a little UI to display some stats about an app at work, and decided to try using Babashka with HTMX for it. Turned out to be a really good experience.

Babashka has pretty much everything you need for a basic web app baked in, and HTMX lets you do dynamic loading on the page without having to bother with a Js frontend.

Best part is that bb can start nREPL with bb --nrepl-server and then you can connect an editor like Calva to it and develop the script interactively.

Definitely recommend checking it out if you need to make a simple web UI.

#!/usr/bin/env bb
(require
 '[clojure.string :as str]
 '[org.httpkit.server :as srv]
 '[hiccup2.core :as hp]
 '[cheshire.core :as json]
 '[babashka.pods :as pods]
 '[clojure.java.io :as io]
 '[clojure.edn :as edn])
(import '[java.net URLDecoder])

(pods/load-pod 'org.babashka/postgresql "0.1.0")
(require '[pod.babashka.postgresql :as pg])

(defonce server (atom nil))
(defonce conn (atom nil))

(def favicon "data:image/x-icon;base64,AAABAAEAEBAAAAAAAABoBQAAFgAAACgAAAAQAAAAIAAAAAEACAAAAAAAAAEAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP//AAD8fwAA/H8AAPxjAAD/4wAA/+MAAMY/AADGPwAAxjEAAP/xAAD/8QAA4x8AAOMfAADjHwAA//8AAP//AAA=")

(defn list-accounts [{:keys [from to]}]
  (pg/execute! @conn
               ["select account_id, created_at
                 from accounts
                 where created_at between to_date(?, 'yyyy-mm-dd') and to_date(?, 'yyyy-mm-dd')"
                from to]))

(defn list-all-accounts [_req]
  (json/encode {:accounts (pg/execute! @conn ["select account_id, created_at from accounts"])}))

(defn parse-body [{:keys [body]}]
  (reduce
   (fn [params param]
     (let [[k v] (str/split param #"=")]
       (assoc params (keyword k) (URLDecoder/decode v))))
   {}
   (-> body slurp (str/split #"&"))))

(defn render [html]
  (str (hp/html html)))

(defn render-accounts [request]
  (let [params (parse-body request)
        accounts (list-accounts params)]
    [:table.table {:id "accounts"}
     [:thead
      [:tr [:th "account id"] [:th "created at"]]]
     [:tbody
      (for [{:accounts/keys [account_id created_at]} accounts]
        [:tr [:td account_id] [:td (str created_at)]])]]))

(defn date-str [date]
  (let [fmt (java.text.SimpleDateFormat. "yyyy-MM-dd")]
    (.format fmt date)))

(defn account-stats []
  [:section.hero
   [:div.hero-body
    [:div.container
     [:div.columns
      [:div.column
       [:form.box
        {:hx-post "/accounts-in-range"
         :hx-target "#accounts"
         :hx-swap "outerHTML"}
        [:h1.title "Accounts"]
        [:div.field
         [:label.label {:for "from"} [:b "from "]]
         [:input.control {:type "date" :id "from" :name "from" :value (date-str (java.util.Date.))}]]

        [:div.field
         [:label.label {:for "to"} [:b " to "]]
         [:input.control {:type "date" :id "to" :name "to" :value (date-str (java.util.Date.))}]]

        [:button.button {:type "submit"} "list accounts"]]
       [:div.box [:table.table {:id "accounts"}]]]]]]])

(defn home-page [_req]
  (render
   [:html
    [:head
     [:link {:href favicon :rel "icon" :type "image/x-icon"}]
     [:meta {:charset "UTF-8"}]
     [:title "Account Stats"]
     [:link {:href "https://cdn.jsdelivr.net/npm/bulma@1.0.0/css/bulma.min.css" :rel "stylesheet"}]
     [:link {:href "https://unpkg.com/todomvc-app-css@2.4.1/index.css" :rel "stylesheet"}]
     [:script {:src "https://unpkg.com/htmx.org@1.5.0/dist/htmx.min.js" :defer true}]
     [:script {:src "https://unpkg.com/hyperscript.org@0.8.1/dist/_hyperscript.min.js" :defer true}]]
    [:body
     (account-stats)]]))

(defn handler [{:keys [uri request-method] :as req}]
  (condp = [request-method uri]
    [:get "/"]
    {:body (home-page req)
     :headers {"Content-Type" "text/html charset=utf-8"}
     :status 200}

    [:get "/accounts.json"]
    {:body (list-all-accounts req)
     :headers {"Content-Type" "application/json; charset=utf-8"}
     :status 200}

    [:post "/accounts-in-range"]
    {:body (render (render-accounts req))
     :status 200}

    {:body (str "page " uri " not found")
     :status 404}))

(defn read-config []
  (if (.exists (io/file "config.edn"))
    (edn/read-string (slurp "config.edn"))
    {:port 3001
     :db {:dbtype   "postgresql"
          :host     "localhost"
          :dbname   "postgres"
          :user     "postgres"
          :password "postgres"
          :port     5432}}))

(defn run []
  (let [{:keys [port db]} (read-config)]
    (reset! conn db)
    (when-let [server @server]
      (server))
    (reset! server
            (srv/run-server #(handler %) {:port port}))
    (println "started on port:" port)))

;; ensures process doesn't exit when running from command line
(when (= "start" (first *command-line-args*))
  (run)
  @(promise))

(comment
  ;; restart server 
  (do
    (when-let [instance @server] (instance))
    (reset! server nil)
    (run)))
354
-1
FRONTEND WEB DEV (clj.social)
submitted 6 months ago by planet@clj.social to c/clojure@lemmy.ml

FRONTEND WEB DEV

https://dev.to/annasdev06/frontend-web-dev-2106

In the ever-evolving landscape of Web Development, the Frontend arena in 2024 has seen a remarkable fusion of creativity, functionality, and technological innovation. Frontend web development, once primarily focused on crafting visually appealing...

#clojure #clj #cljs !clojure@lemmy.ml @clojure

355
1
submitted 6 months ago by planet@clj.social to c/clojure@lemmy.ml
356
0
submitted 6 months ago by yogthos@lemmy.ml to c/clojure@lemmy.ml
357
4
submitted 6 months ago by planet@clj.social to c/clojure@lemmy.ml
358
1
submitted 6 months ago by yogthos@lemmy.ml to c/clojure@lemmy.ml
359
4
submitted 6 months ago by clojure@clj.social to c/clojure@lemmy.ml

Clojure Deref (May 3, 2024)

https://clojure.org/news/2024/05/03/deref

Welcome to the Clojure Deref! This is a weekly link/news roundup for the Clojure ecosystem (feed: RSS). Thanks to Anton Fonarev for link aggregation. Podcasts and videos Clojure visual-tools meeting 24 - badspreadsheet & HTMX - Sci...

#clojure #clj #cljs !clojure@lemmy.ml @clojure@lemmy.ml

360
2
submitted 6 months ago by mindaslab@lemmy.ml to c/clojure@lemmy.ml
361
3
submitted 6 months ago by planet@clj.social to c/clojure@lemmy.ml

PG2 release 0.1.12

https://grishaev.me/en/pg-0-1-12

PG2 version 0.1.12 is out. Aside from internal refactoring, there are several features I’d like to highlight. First, the library is still getting faster. The latest benchmarks prove 15-30% performance gain when consuming SELECT results. Actual...

#clojure #clj #cljs !clojure@lemmy.ml @clojure

362
1
submitted 6 months ago by planet@clj.social to c/clojure@lemmy.ml

Ep 114: Brand New, Again

https://clojuredesign.club/episode/114-brand-new-again/

Each week, we discuss a different topic about Clojure and functional programming. If you have a question or topic you'd like us to discuss, tweet @clojuredesign, send an email to feedback@clojuredesign.club, or join the #clojuredesign-podcast...

#clojure #clj #cljs !clojure@lemmy.ml @clojure

363
0
submitted 6 months ago by yogthos@lemmy.ml to c/clojure@lemmy.ml
364
1
submitted 6 months ago by planet@clj.social to c/clojure@lemmy.ml

Clojurists Together project - Scicloj community building - April 2024 update

https://scicloj.github.io/blog/clojurists-together-project-scicloj-community-building-april-2024-update/

The Clojurists Together organisation has decided to sponsor Scicloj community building for Q1 2024, as a project by Daniel Slutsky. The project is taking place in February, March, and April 2024. Here is Daniel’s update for April. Here are the...

#clojure #clj #cljs !clojure@lemmy.ml @clojure

365
2
submitted 6 months ago by planet@clj.social to c/clojure@lemmy.ml

XT24 Fintech Conference

https://juxt.pro/blog/XT24

Come to our first fintech event

#clojure #clj #cljs !clojure@lemmy.ml @clojure

366
1
submitted 6 months ago by planet@clj.social to c/clojure@lemmy.ml

OSS Updates March and April 2024

https://codewithkira.com/2024-04-30-clojurists-together-update-mar-apr-2024.html

This is a summary of the open source work I've spent my time on throughout March and April, 2024. Overall it was a really insightful couple of months for me, with lots of productive discussions and meetings happening among key contributors to...

#clojure #clj #cljs !clojure@lemmy.ml @clojure

367
3
submitted 6 months ago by mindaslab@lemmy.ml to c/clojure@lemmy.ml
368
3
submitted 6 months ago by planet@clj.social to c/clojure@lemmy.ml

OSS Updates March and April 2024

https://codewithkira.com/2024-04-30-clojurists-together-update-mar-apr-2024.html.html

This is a summary of the open source work I've spent my time on throughout March and April, 2024. Overall it was a really insightful couple of months for me, with lots of productive discussions and meetings happening among key contributors to...

#clojure #clj #cljs !clojure@lemmy.ml @clojure

369
1
submitted 6 months ago by planet@clj.social to c/clojure@lemmy.ml

Clojure 1.12.0-alpha11

https://clojure.org/news/2024/04/30/clojure-1-12-alpha11

Clojure 1.12.0-alpha11 is now available! Find download and usage information on the Downloads page. CLJ-2848 - Qualified instance methods without param-tags should use the qualified method class, not the target object type CLJ-2847 - Improve...

#clojure #clj #cljs !clojure@lemmy.ml @clojure

370
1
submitted 6 months ago by clojure@clj.social to c/clojure@lemmy.ml

Clojure 1.12.0-alpha11

https://clojure.org/news/2024/04/30/clojure-1-12-alpha11

Clojure 1.12.0-alpha11 is now available! Find download and usage information on the Downloads page. CLJ-2848 - Qualified instance methods without param-tags should use the qualified method class, not the target object type CLJ-2847 - Improve...

#clojure #clj #cljs !clojure@lemmy.ml @clojure@lemmy.ml

371
1
submitted 6 months ago by planet@clj.social to c/clojure@lemmy.ml

Humble Chronicles: Shape of the Component

https://tonsky.me/blog/humble-defcomp/

Last time I ran a huge experiment trying to figure out how components should work in Humble UI. Since then, I’ve been trying to bring it to the main. This was trickier than I anticipated — even with a working prototype, there are still lots of...

#clojure #clj #cljs !clojure@lemmy.ml @clojure

372
1
submitted 6 months ago by planet@clj.social to c/clojure@lemmy.ml

What I learned from Alcoa

https://ericnormand.substack.com/p/what-i-learned-from-alcoa

Rally to a vision to help people change

#clojure #clj #cljs !clojure@lemmy.ml @clojure

373
1
submitted 6 months ago by planet@clj.social to c/clojure@lemmy.ml

OSS updates March and April 2024

https://blog.michielborkent.nl/oss-updates-mar-apr-2024.html

In this post I'll give updates about open source I worked on during March and April 2024.To see previous OSS updates, go here.SponsorsI'd like to thank all the sponsors and contributors that make this work possible. Without you, the below projects...

#clojure #clj #cljs !clojure@lemmy.ml @clojure

374
1
submitted 6 months ago by planet@clj.social to c/clojure@lemmy.ml

Humble Chronicles: The Inescapable Objects

https://tonsky.me/blog/humble-objects/

In HumbleUI, there is a full-fledged OOP system that powers lower-level component instances. Sacrilegious, I know, in Clojure we are not supposed to talk about it. But... Look. Components (we call them Nodes in Humble UI because they serve the same...

#clojure #clj #cljs !clojure@lemmy.ml @clojure

375
2
submitted 6 months ago by planet@clj.social to c/clojure@lemmy.ml

Rama is a testament to the power of Clojure

https://blog.redplanetlabs.com/2024/04/30/rama-is-a-testament-to-the-power-of-clojure/

It took more than ten years of full-time work for Rama to go from an idea to a production system. I shudder to think of how long it would have taken without Clojure. Rama is a programming platform that integrates and generalizes backend...

#clojure #clj #cljs !clojure@lemmy.ml @clojure

view more: ‹ prev next ›

Clojure programming language discussion

451 readers
1 users here now

Clojure is a Lisp that targets JVM and JS runtimes

Finding information about Clojure

API Reference

Clojure Guides

Practice Problems

Interactive Problems

Clojure Videos

The Clojure Community

Clojure Books

Tools & Libraries

Clojure Editors

Web Platforms

founded 4 years ago
MODERATORS