Fennel wiki: cljlib

Cljlib is an experimental library that brings a lot of stuff from Clojure's core library into Fennel. Its goal is to allow porting of Clojure code to Fennel with minimal syntactic change. The source code can be found at https://gitlab.com/andreyorst/fennel-cljlib.

A brief demonstration of its capabilities is provided below. For a full list of provided functions, please consult the documentation

(require-macros :io.gitlab.andreyorst.cljlib.core)
(ns todo-app
  "An overcomplicated todo app."
  (:require
   [io.gitlab.andreyorst.cljlib.core
    :refer [agent await deref send
            get assoc conj
            map filter run!
            first second last
            println str
            random-uuid]]))

(defn create-todo
  "Define a todo item as a map"
  [title]
  {:id (random-uuid)
   :title title
   :completed false})

;; Create an agent to manage the todo list
(def todos (agent []))

(defn add-todo
  "Function to add a todo item using the agent"
  [agent title]
  (send agent conj (create-todo title)))

(defn complete-todo
  "Function to complete a todo item using the agent"
  [agent todo-id]
  (send agent
        (fn [todos]
          (map (fn [todo]
                 (if (= (get todo :id) todo-id)
                     (assoc todo :completed true)
                     todo))
               todos))))

(defn remove-todo
  "Function to remove a todo item using the agent"
  [agent todo-id]
  (send agent
        (fn [todos]
          (filter
           (fn [todo]
             (not= (get todo :id) todo-id))
           todos))))

(defn display-todos
  "Function to display the current state of the todo list"
  [agent]
  (println "Todo List:")
  (run! (fn [todo]
          (println
           (str (if (get todo :completed) "[x] " "[ ] ")
                (get todo :title))))
        (deref agent)))

(defn -main []
  (add-todo todos "Learn Fennel")
  (add-todo todos "Learn Clojure")
  (add-todo todos "Build a todo app with cljlib")

  (await todos)

  (display-todos todos)

  (let [todo-to-complete (get (first (deref todos)) :id)]
    (complete-todo todos todo-to-complete)
    (await todos))

  (display-todos todos)

  (let [todo-to-remove (get (second (deref todos)) :id)]
    (remove-todo todos todo-to-remove)
    (complete-todo todos (last (deref todos)))
    (await todos))

  (display-todos todos))

(-main)

;;; Program output:

;; Todo List:
;; [ ] Learn Fennel
;; [ ] Learn Clojure
;; [ ] Build a todo app with cljlib
;; Todo List:
;; [x] Learn Fennel
;; [ ] Learn Clojure
;; [ ] Build a todo app with cljlib
;; Todo List:
;; [x] Learn Fennel
;; [ ] Build a todo app with cljlib