Professional Clojure user since 2013.
Programming with concrete data, like EDN or JSON.
HTML rendering library by James Reeves in 2009.
(defn example-page [title] (h/html5 [:head [:title title]] [:body [:div.container [:h1 title] [:p "Hello world!"]]]))
Like this:
{:shape/kind :circle :shape/color :red :shape/position [3 3] :shape/radius 5}
Not like this:
public class Circle extends Shape { public Color color; public Point position; public double radius; public Circle(Color startColor, Point startPoint, double startRadius { color = startColor; position = startPosition; radius = startRadius; } public void setColor(Color newColor) { color = newColor; } // ... you get the idea ... }
Not even like this:
data Shape = Circle { color :: Color , position :: Point , radius :: Double } | Rectangle { ... } | ...
Routing library created by James Reeves in 2009.
(defroutes app (context "/products" (GET "/" [] (products/list)) (GET "/:pid" [pid :<< as-uuid] (products/get pid)) (GET "/search" [q] (products/search q)) (POST "/" {body :body} (products/new body)) (route/not-found "<h1>Page not found</h1>"))
Routing library created by James Reeves in 2016.
{"/products" {[:get] [:products/list] [:get "/" pid] [:products/get ^uuid pid] [:get "/search" #{q}] [:products/search q] [:post {body :body}] [:products/new body]}}
(defroutes app (context "/products" (GET "/" [] (products/list)) (GET "/:pid" [pid :<< as-uuid] (products/get pid)) (GET "/search" [q] (products/search q)) (POST "/" {body :body} (products/new body)) (route/not-found "<h1>Page not found</h1>"))
{"/products" {[:get] [:products/list] [:get "/" pid] [:products/get ^uuid pid] [:get "/search" #{q}] [:products/search q] [:post {body :body}] [:products/new body]}}
When you encounter a problem, solve it by creating a language where it's easy to solve.
You already know how to work with data!
Instead of having a compiler for your macro language, you can have multiple interpreters for your data language.
Can be slow.
IDEs won't support your little language (out of the box).
(rf/reg-event-db ::input-changed (fn [db [_ value]] (assoc db :input-value value))) [:input {:type "text" :on-change #(rf/dispatch [::input-changed %])}]
Beware of implementing a general-purpose programming language!
EDN is rich enough and easy to work with!
Consider: JSON vs. EDN vs. XML
{:adapter/jetty {:port 8080, :handler #ig/ref :handler/greet} :handler/greet {:name "Alice", :birthday #inst "1987-10-25T00:00Z"}}
{ "adapter/jetty": { "port": 8080, "handler": ["ig/ref", "handler/greet"] }, "handler/greet": { "name": "Alice", "birthday": "1987-10-25T00:00Z" } }
There's a controversial library for creating a parser for your little language…
clojure.spec
Seriously, check out s/conform
.
http://miikka.me/slides/data-the-ultimate/
follow me on twitter: @arcatan
Photo credit: Kenneth Dellaquila. CC-BY-NC. Cropped.