Mihael Konjevic ClojuTRE 2017 Interview

Mihael Konjevic

ClojuTRE 2017 Speaker Interview

Please share:

Mihael Konjevic ClojuTRE 2017 Interview

Mihael Konjevic will be giving a talk at ClojuTRE 2017. His talk is called Developing (with) Keechma.

Follow him on his Homepage, GitHub and Twitter.

PurelyFunctional.tv: What is your favorite feature of Clojure?

Mihael Konjevic: If I would have to pick one, it would be immutable data structures. I'm mostly programming frontend applications, and it's crazy how much productive and care free I feel since I've switched to ClojureScript. I was working on a big TypeScript application last year, and the first mind boggling bug that I've introduced was related to mutability. For me immutable data structures are a 100% win.

PF.tv: What is your least favorite feature of Clojure?

MK: Debugging can be painful. After a while you get the feeling where the problem might lie, but it was a huge pain when I was beginning.

PF.tv: Can you briefly describe your talk?

MK: I will talk about the Keechma (frontend) framework and why it exists. Before doing ClojureScript I was a core contributor to the CanJS framework, and I when I started working on my app (in Re-frame and Reagent), I've felt that there were a lot of things missing. The fundamentals were great, but I had to manually take care of a lot of stuff that CanJS had solved out of the box. First cut of Keechma was built inside the codebase of that app, but then I've decided to extract it, document it and release it as a separate project. In this talk I'll cover the pains that Keechma is fixing, and how and why I've fixed them in a way that I did.

PF.tv: Why did you choose this topic?

MK: Every framework is a formalized set of it's authors' beliefs, so I wanted to talk about these beliefs and how they make frontend development easier, simpler and more deterministic.

PF.tv: What is one thing I will be able to do after watching your talk?

MK: My goal #1 is to motivate people to try Keechma, but I want to do it in a way where I present the decisions behind it. Even if you don't try Keechma afterwards, you will have more in depth understanding of the tradeoffs that are made when building a framework.

PF.tv: What are the three most important concepts I need to know to follow the conversation?

MK: Experience with any similar framework - like Re-frame or React + Redux should be enough to allow you to follow the talk. My plan is to talk about the philosophy behind Keechma, so it's useful if you are familiar with different approaches to the same problems. If I would have to pick three most important principles in Keechma they would be:

  1. Unidirectional data flow
    • Route params are derived from the URL
    • Application state is derived from the route params & UI is derived from the application state
  2. Automatic synchronization of entities' states
    • An entity is any data loaded into the app that has identity (e.g. :id column)
    • Entities are stored in the EntityDB (Keechma sub library)
    • EntityDB propagates entity state to every place where that entity is displayed in the UI
  3. Enforced lifecycle (and memory safety)
    • Automatically load data on route change
    • Automatically clean up stale data on route change
    • Automatically set up event listeners on route change (e.g. listener on the WebSocket)
    • Automatically tear down event listeners on route change

PF.tv: Where can people follow you online?

MK: They can find me on Twitter and on GitHu.

PF.tv: Are there any projects you'd like people to be aware of? How can people help out?

MK: Yeah, checkout Keechma 🙂 and if you're into GraphQL. Also, if you tried to use Keechma let me know what were your pain points - conceptually or documentation wise.

PF.tv: What one feature from another language would you like to see in Clojure?

MK: Maybe I'm still in the honey moon phase with Clojure, but I don't feel like there's anything missing in the language.

PF.tv: What is your favorite Clojure function or macro?

MK: I'd say go blocks. They powers a lot of internal code in Keechma and Keechma Toolbox where more imperative style is appropriate. It is great to have it at disposal when needed.

This interview is not sponsored by nor affiliated with the conference or its organizers. It is in no way official. It is simply curated and organized public information about the conference.

Get on the mailing list!


Permalink

Weekly links #27

I’ve just returned from EuroClojure, it was amazing! Thank you everybody who brought it to us.

Here are some interesting links I found on Medium:

Permalink

Slacker 0.15 released

After another year of development, I'm proud to announce a new major release of my Clojure RPC library, slacker. This release, 0.15.0, includes an update on wire protocol, some performance improvement and bugfix.

The request extension

This release of slacker client use v6 protocol by default. The server can still accept v5 protocol for backward compatibility.

The v6 protocol added an extension field to request and response packet. By using this field, you can exchange some metadata in RPC call. A typical use case is for distributed tracing. Trace ID is passed as extension.

In the API level, we kept the non-invasive principle. Extensions will be injected as var bindings.

(require '[slacker.common :refer [with-extension]])
(require '[slacker.client :as sc])

(def conn (sc/slackerc "127.0.0.1:2104"))
(sc/defn-remote conn slacker.example.api/timestamp)

(def extension-id 16)
(with-extension {extension-id "extension-value"}
  (timestamp))

A more typical usage of extension is in interceptors. slacker-htrace use extension to pass htrace trace id along with rpc call.

(defn client-interceptor [^Tracer tracer span-id-extension-id]
  {:pre (fn [req]
          (let [scope-name (str (:fname req) ":outer")
                trace-scope (.newScope tracer scope-name)]
            (-> req
                (assoc ::trace-scope trace-scope)
                (update :extensions assoc
                        span-id-extension-id
                        (from-span-id(.getSpanId ^TraceScope trace-scope))))))
   :post (fn [resp]
           (when-let [scope (::trace-scope resp)]
             (.close ^TraceScope scope))
           (dissoc resp ::trace-scope))})

(defn server-interceptor [^Tracer tracer span-id-extension-id]
  {:before (fn [req]
             (let [scope-name (str (:fname req) ":inner")
                   span-id (-> req :extensions (get span-id-extension-id) to-span-id)
                   trace-scope (.newScope tracer scope-name span-id)]
               (-> req
                   (assoc ::trace-scope trace-scope))))
   :after (fn [resp]
            (when-let [scope (::trace-scope resp)]
              (.close ^TraceScope scope))
            (dissoc resp ::trace-scope))})

Flexible server thread pool

Previously, you can only configure one thread pool for all exposed namespace. This adds risk that one backend issue may exhaust all your server threads. And your server stops respond requests for any namespace.

To isolate the execution for namespaces, slacker 0.15 added support for finer thread pool configuration.

(start-slacker-server [(the-ns 'slacker.example.api) (the-ns 'slacker.example.api2)]
                      2104
                      :executors {"slacker.example.api"
                                   (ThreadPoolExecutor. 10 10
                                                        0 TimeUnit/MINUTES
                                                        (LinkedBlockingQueue. 100)
                                                        (ThreadPoolExecutor$AbortPolicy.))})

Once all your execution in slacker.example.api blocked, it won't affect requests to slacker.example.api2.

Bugfix and performance improvement

There are some more fixes in release:

  • Fixed issue in stop-slacker-server
  • Use platform specific buffer allocator for (de)serialization
  • Improved client side error report. Full context can be accessed via ex-data.

Middleware

Also I created two example middleware for slacker:

Permalink

Server Side Rendering at modnakasta.ua

I’ve decided to translate an article I wrote for modnaKasta technical blog since it should be fairly interesting for a wider audience than just Russian-speaking people.

modnakasta.ua is a single page application right now, which uses React internally and is written in ClojureScript. But we care about Google and people experience, which means we certainly care about server-side rendering.

Ancientry

Since the whole front-end is in React, which promises to make app renderable without having access to DOM - in Node.js in particular - the first idea was to render everything using Node.js. Doesn’t feel that fuzzy, does it? Especially given that there is a new shiny super-fast JS engine in Java 8: Nashorn. And first experiments showed that it’s indeed very fast, faster than Node.js.

“That’s great,” I thought and we started building an app (not SSR, an app itself). When the app became at least somewhat usable the time has come for a reality check. Loading our ~2-3k loc application into Nashorn proved difficult: 8 Gb of heap was barely enough to load JS file and after 30 seconds of hard work, it spits “this expression in your JS is invalid” error. Fixing few of those errors (mostly by commenting code) showed that there is no way we could develop with an environment like that.

Antiquity

So the Node.js at last. The architecture was simple: we put compiled JS file inside of API server uber jar, on start write it somewhere, and run Node.js against it. After that communicate with Node via HTTP: proxy user requests there, proxy rendered HTML back.

Because Node.js is single-threaded it’s totally wrong to have a single process - so our API server becomes a process pool manager and a load balancer.

Also, we make a request for data while a component is mounted. Which is fine for the browser, you just wait for a bit, the response comes back and the browser will render that data. But on server user request is already gone: your first version of an “empty” component was already sent to a user because rendering process does not wait for the data to be received.

Which was fixed by making it two-pass renderer: first you rendered to kick off the data gather process, and when all XHR activity stops, app is rendered one more to have full content. That takes around 300 ms on a fairly simple page in optimistic case.

Can’t forget to mention that Node.js also leaked memory. Profilers did not help so I went lazy uwsgi way: made a Node process restart every 1000 requests.

But what won’t you sacrifice for the sake of result? So we’ve got this system in place (not in production yet though) and I went to Philly for Clojure/Conj 2015.

Enlightenment

Weirdly I did not plan on attending Allen Rohner’s “Optimizing ClojureScript Apps For Speed” which taught me that descriptions suck. There was nobody in the lobby though so I became bored and went there.

Core idea is following: Clojure 1.7 (came out 5 months before that, in June 2015) gained an ability to have a single .cljc file which can be compiled by both Clojure (which usually lives in .clj files) and ClojureScript (.cljs files). Let’s say this is a React component which renders an image:

(defc Image [image-source]
  [:img {:src image-source}]]

Here defc is a macro which transforms the code into React calls. Here’s a result (roughly):

(def Image (js/React.createComponent {
  :render (fn []
            (js/React.createElement "img" 
              {:src (get js/this.args :image-source)}))})) 

But that’s what macro generates when we compile into JavaScript. What if during execution on JVM (or, in Clojure) it will make this code into a function, returning a string <img src="...">?

(defn Image [image-source]
  (format "<img src=\"%s\">" image-source))

I wrote first version of this rendering for Rum back in January 2016, which Nikita (author of Rum) and other contributors developed into a properly working thing. We’ve got a server-side rendering, but without React runtime, in JVM, with synchronous (yay!) network reads, with multithreading: in other words, pure joy!

Fruits

Synchronous network reads are good because until data from a top-level component is received from the server, inner components (which are dependent on that data) sit there waiting. But right after data is there, inner components are rendered/initialized and start fetching their own data. So the data dependency management here is really simple.

Also, if you render your HTML in the same process your API is running, there is no need to go through network and HTTP. Clojure’s Ring protocol is just a function which accepts a request as an argument, so you can call your whole app with a simple map (which is what request in Ring is) and get response back. XHR looks like that for ClojureScript:

(defn xhr [params callback]
  (let [req (js/XMLHttpRequest.)]
    (set-params req params)
    (set-callback req callback)))

And like that for Clojure (app is our HTTP API):

(defn xhr [params callback]
  (callback (app (params->http-request params)))

Of course, real implementations are a bit longer, setting headers, parsing JSON, etc. By the way, there is an interesting story about JSON: right after Black Friday 2016, when our architecture proved to be a success, I was showing to somebody how it works and saw in MiniProfiler that serializing JSON takes quite a bit of time. Obviously parsing is not free as well.

54 lines of changes later and now we pass unserialized data to server rendering: takes less time and less memory (minus string for JSON and minus newly parsed data). Pleasantly, median time for rendering HTML went down from 110 to 80 ms. :)

Also interesting that we have a cheat (or optimization) around caching and user-specific content: everything that depends on a current user is rendered only on a client. It’s a compromise: users see “anonymous” version of a site initially for a few moments, but in exchange, we can cache rendered HTML for everyone. This makes us able to look like we’re not sweating a bit during sharp increases in traffic. :)

The End

And they lived happily ever after. And you can go to modnakasta.ua by yourself and click around to see how that stuff works. Also, look at the source HTML server gives you, this all is rendered in JVM, with absolutely no JavaScript.

Permalink

Server Side Rendering at modnakasta.ua

I’ve decided to translate an article I wrote for modnaKasta technical blog since it should be fairly interesting for a wider audience than just Russian-speaking people.

modnakasta.ua is a single page application right now, which uses React internally and is written in ClojureScript. But we care about Google and people experience, which means we certainly care about server-side rendering.

Ancientry

Since the whole front-end is in React, which promises to make app renderable without having access to DOM - in Node.js in particular - the first idea was to render everything using Node.js. Doesn’t feel that fuzzy, does it? Especially given that there is a new shiny super-fast JS engine in Java 8: Nashorn. And first experiments showed that it’s indeed very fast, faster than Node.js.

“That’s great,” I thought and we started building an app (not SSR, an app itself). When the app became at least somewhat usable the time has come for a reality check. Loading our ~2-3k loc application into Nashorn proved difficult: 8 Gb of heap was barely enough to load JS file and after 30 seconds of hard work, it spits “this expression in your JS is invalid” error. Fixing few of those errors (mostly by commenting code) showed that there is no way we could develop with an environment like that.

Antiquity

So the Node.js at last. The architecture was simple: we put compiled JS file inside of API server uber jar, on start write it somewhere, and run Node.js against it. After that communicate with Node via HTTP: proxy user requests there, proxy rendered HTML back.

Because Node.js is single-threaded it’s totally wrong to have a single process - so our API server becomes a process pool manager and a load balancer.

Also, we make a request for data while a component is mounted. Which is fine for the browser, you just wait for a bit, the response comes back and the browser will render that data. But on server user request is already gone: your first version of an “empty” component was already sent to a user because rendering process does not wait for the data to be received.

Which was fixed by making it two-pass renderer: first you rendered to kick off the data gather process, and when all XHR activity stops, app is rendered one more to have full content. That takes around 300 ms on a fairly simple page in optimistic case.

Can’t forget to mention that Node.js also leaked memory. Profilers did not help so I went lazy uwsgi way: made a Node process restart every 1000 requests.

But what won’t you sacrifice for the sake of result? So we’ve got this system in place (not in production yet though) and I went to Philly for Clojure/Conj 2015.

Enlightenment

Weirdly I did not plan on attending Allen Rohner’s “Optimizing ClojureScript Apps For Speed” which taught me that descriptions suck. There was nobody in the lobby though so I became bored and went there.

Core idea is following: Clojure 1.7 (came out 5 months before that, in June 2015) gained an ability to have a single .cljc file which can be compiled by both Clojure (which usually lives in .clj files) and ClojureScript (.cljs files). Let’s say this is a React component which renders an image:

(defc Image [image-source]
  [:img {:src image-source}]]

Here defc is a macro which transforms the code into React calls. Here’s a result (roughly):

(def Image (js/React.createComponent {
  :render (fn []
            (js/React.createElement "img" 
              {:src (get js/this.args :image-source)}))})) 

But that’s what macro generates when we compile into JavaScript. What if during execution on JVM (or, in Clojure) it will make this code into a function, returning a string <img src="...">?

(defn Image [image-source]
  (format "<img src=\"%s\">" image-source))

I wrote first version of this rendering for Rum back in January 2016, which Nikita (author of Rum) and other contributors developed into a properly working thing. We’ve got a server-side rendering, but without React runtime, in JVM, with synchronous (yay!) network reads, with multithreading: in other words, pure joy!

Fruits

Synchronous network reads are good because until data from a top-level component is received from the server, inner components (which are dependent on that data) sit there waiting. But right after data is there, inner components are rendered/initialized and start fetching their own data. So the data dependency management here is really simple.

Also, if you render your HTML in the same process your API is running, there is no need to go through network and HTTP. Clojure’s Ring protocol is just a function which accepts a request as an argument, so you can call your whole app with a simple map (which is what request in Ring is) and get response back. XHR looks like that for ClojureScript:

(defn xhr [params callback]
  (let [req (js/XMLHttpRequest.)]
    (set-params req params)
    (set-callback req callback)))

And like that for Clojure (app is our HTTP API):

(defn xhr [params callback]
  (callback (app (params->http-request params)))

Of course, real implementations are a bit longer, setting headers, parsing JSON, etc. By the way, there is an interesting story about JSON: right after Black Friday 2016, when our architecture proved to be a success, I was showing to somebody how it works and saw in MiniProfiler that serializing JSON takes quite a bit of time. Obviously parsing is not free as well.

54 lines of changes later and now we pass unserialized data to server rendering: takes less time and less memory (minus string for JSON and minus newly parsed data). Pleasantly, median time for rendering HTML went down from 110 to 80 ms. :)

Also interesting that we have a cheat (or optimization) around caching and user-specific content: everything that depends on a current user is rendered only on a client. It’s a compromise: users see “anonymous” version of a site initially for a few moments, but in exchange, we can cache rendered HTML for everyone. This makes us able to look like we’re not sweating a bit during sharp increases in traffic. :)

The End

And they lived happily ever after. And you can go to modnakasta.ua by yourself and click around to see how that stuff works. Also, look at the source HTML server gives you, this all is rendered in JVM, with absolutely no JavaScript.

Permalink

React Lifecycle for Re-frame

A guide to the React Lifecycle Methods for Re-frame

Reagent, which is used by Re-frame, gives you two methods for creating components that will serve you 90% of the time. Those are the Form-1 and Form-2 components that are based on functions. However, for that last 10%, with Form-3 components, you're almost dropped down right into React and its Lifecycle Methods.

The React Lifecycle makes sense. It's exactly the rope you need to to climb to the top of the hill. However, it's also way more rope than you need to get tangled up in a mess of effectful spaghetti. I've seen it on React projects. It's what people hate the most about React because it's the part that is so easy to make a mess with.

Luckily, we are functional programmers. We don't like mixing in our state changes and ajax requests in our components. And since we don't have to even touch that part of React 90% of the time, we're protected from the worst offenses. Let me just give an example of what people do with React: they fetch data from the server from within their components. They treat loading certain components into the DOM kind of like a page load that now requires a bunch of data from the server. It means that when I want to load a UserView component, it pass it the UserID in the constructor and it will go and fetch the data from the server when it loads into the DOM. What if I already have the user data? How do I test that?

In ClojureScript, and certainly in Re-frame, we tend to separate out those things. The UserView component might take a UserID to build it, but something else is going to be fetching that user data and putting into the Database. The component should not know where the data came from. That's basically how 90% of the cases are eliminated--basic functional programming.

But that last 10% need Lifecycle Methods. There are still stateful things happening to our components. For instance, before mounting, there simply is no DOM element. If you need to access the DOM element, you have to wait until after mounting. We need to hook into React Lifecycle Methods.

Luckily, we can simplify those methods a lot. The React Documentation lists ten Lifecycle Methods. In practice, in Re-frame, we only ever use four of those. Let me go over in detail each of those five. I'll go through each one, saying when to use it and how.

Form-3 components

A Form-3 component takes this basic shape:

(defn complex-component [a b c]
  (let [state (reagent/atom {})] ;; you can include state
    (reagent/create-class
      {:component-did-mount
       (fn [] (println "I mounted"))

       ;; ... other methods go here
       ;; see https://facebook.github.io/react/docs/react-component.html#the-component-lifecycle
       ;; for a complete list

       ;; name your component for inclusion in error messages
       :display-name "complex-component"

       ;; note the keyword for this method
       :render-reagent
       (fn [a b c]
         [:div {:class c}
           [:i a] " " b])})))

It's a function, like the other Forms. It gives you an opportunity to initialize some local state. But instead of returning Hiccup (like Form-1) or a function (like Form-2), it returns the value from a call to reagent.core/create-class. That function takes a map of the Lifecycle Methods you'd like to implement. The only one that is required is :render-reagent, which is the render function you're used to in the other two Forms. You should also pass in a :display-name with the name of the component in a string. That will help you debug. Here are the other Methods:

:component-did-mount

This method is called just once right after the component is mounted into the DOM. This is the first time that you will have access to the actual DOM element connected with this component. The first and only argument to this function is the component itself. You can call reagent.core/dom-node to get that and do whatever you need to with it.

Why would you implement this method? Well, let's say you wanted to embed a component that is not a React component into your page. For instance, you wanted to use CodeMirror or some other editor. CodeMirror asks you to construct a CodeMirror object with a DOM node as an argument. It will then embed the editor right into the DOM, basically unmanaged by React. As long as you don't re-render, that editor will still be in the DOM.

:component-did-mount
(fn [comp]
  (js/CodeMirror. (reagent/dom-node comp)))

You can also use this method to draw. Let's say your render method renders an HTML canvas. You can put the draw methods in here.

:component-did-mount
(fn [comp]
  (let [node (reagent/dom-node comp)
        ;; some canvas stuff
        ctx (.getContext node "2d")]
    (.fillRect ctx 10 10 10 10)))

Note: we used :component-did-mount in the Externally Managed Components lesson of Building Re-frame Components to make a component out of the CodeMirror editor.

:reagent-render

This is the render method you normally create with a Form-1 or Form-2 component. It's a function that returns Hiccup and it includes all of the Reagent magic to let it re-render when the arguments change or a Subscription it derefs changes. This one is required, or how else would you render HTML?

:component-did-update

This method is called just after re-rendering. That means that the DOM nodes are potentially totally re-freshed from the return value of the render method. You shouldn't trouble yourself with what has changed. That's React's job. Just assume that you'll have to redo everything you did in :component-did-mount again. For instance, you can redraw that square:

:component-did-update
(fn [comp]
  (let [node (reagent/dom-node comp)
        ctx (.getContext node "2d")]
    (.fillRect ctx 10 10 10 10)))

:component-will-unmount

This method is called just before your component is stripped out of the DOM and thrown away. You can use this to clean up anything you've created. For instance, if you needed to register some event handlers in that CodeMiror editor you embedded, this would be the place to unregister those events.

Note that in JS React, a lot of Components will register global events like window.resize. Then they need to unregister them here. Or they will do a lot of window.setTimeouts in the component and they'll need to cancel them. In Re-frame, you won't be doing a lot of that stuff. If you need to respond to resize events, dispatch an event in response and store the width and height in the database. Even though most cases are covered, still, anything the component has done to the DOM may need to be undone, so you might need this.

Methods you probably don't need

Okay, so I've said that you only need a few of the methods React gives you. I'm also going to go through the all of the ones that you won't need. I'll say why you don't need them. But I would like to explain them in that off chance that you really do need them. No one can know what you'll need until you need it.

:component-will-mount

This method is called right after the constructor but just before mounting into the DOM. It's an awkward part of the life of a component: the component has already been set up, but it still doesn't have a DOM node. What would you do here? You've already had a chance to set up some state. And you've still got to wait for that DOM node. Well, the answer is that even JavaScript Reacters don't recommend doing anything here. Re-framers should be setting stuff up in the outer function of Form-3.

VERDICT: ignore it.

:component-will-receive-props

This method is called when the arguments to your component are changed in the parent. In JS React, this is where you'd check on stuff like whether you want to fetch some new user data from the server. The UserID could have changed.

In general, Reagent wraps this up in such a nice package, you're not going to need this. If you need data from the server, use a subscription and save the data in the database. The component will update cleanly and easily as needed.

VERDICT: ignore it; use the database and subscriptions for data from the server.

:should-component-update

This method is called to ask the component whether it thinks it should re-render. It looks to React like something has changed. This is the component's chance to check to see if the changes actually need to be re-rendered. A lot is written about how to do this calculation quickly and save renderings. But guess what! Reagent has a default implementation for this method, and it does this really well. Probably better than you could do. Because ClojureScript uses immutable data, it's really easy to know when things have changed. If you're comparing the old arguments and the new arguments, if they are the same object, nothing has changed, because that object is immutable. That one check is so quick and saves so many renderings, you're already ahead of the game.

VERDICT: leave Reagent's default implementation; it's fast enough.

:component-will-update

This method is called after React checked if the component should update and the component said yes. Now is the component's chance to get stuff ready for the upcoming re-render. But what preparations will you make? You should be doing serious calculations in Dynamic Subscriptions, not in the component. Doing that, you'll save even more unnecessary re-renders.

The fact is, I have never needed this method, I can't imagine needing this, but I also can't rule out its usefulness for some odd case I've never dealt with. So here's what you'll need to know. You won't know why you're updating: is it an argument change or a subscription change? If you need to, you can check if the arguments have changed. The new arguments are passed to your function and you can get the new ones with reagent.core/children.

:component-will-update
(fn [comp [_ & [a b c :as new-args]]]
  (let [old-args (reagent/children comp)]
    (when (not= new-args old-args)
      (js/console.log "Args have changed"))))

VERDICT: I seriously doubt you'll need it; calculate anything you need in Dynamic Subscriptions.

Conclusions

Re-frame gives you a lot of structure for your frontend application. You should use it. As functional programmers, we tend to want to separate out the rendering from the state updating. So we treat React like a pure, functional View. However, we can't avoid some state and effects. We tend to reach out from within our functional bubble when we need to go outside of React and modify the DOM directly.

React provides for this with its Lifecycle Methods. There is one at each stage of a component's life. However, most of them are uninteresting to a Re-framer. We have a place for state (the Database), we have a place for Effects, and we have a place for preparing the data components will need (Subscriptions). Use those, keep your components simple, and relax 🙂

The ones that are interesting directly relate to updating the DOM at certain strategic points: the first time the DOM is rendered, after each re-render, and when the component is removed from the DOM. Other than that, ClojureScript, Reagent, and Re-frame have your back.

Get on the mailing list!


Permalink

Clojurescript Ethereum Developer

Clojurescript Ethereum Developer

district0x | Anywhere
remote
A network of decentralized markets and communities
$60000 - $100000

Disintermediate global and local marketplaces with the power of decentralized communities!

We launched Ethlance in January 2017. At the time, it was one of the first functional applications to go live on Ethereum's MainNet and to this day is one of the most used. Districts are a generalization on Ethlance's form and function, built using Clojurescript, re-frame and web3.js. We are a 100% open source and remote project, and are looking to secure our first engineering hire to accelerate the deployment of a framework for launching new districts.

The ideal candidate will have:

  • Experience with building front-end for web applications using Clojurescript
  • Experience with using re-frame v0.8 library
  • Willing to accept salary paid in Ether/Bitcoin cryptocurrency

Nice to have:
Deep understanding of how the Ethereum network works

  • Experience building smart contracts with Solidity

About district0x

The district0x Network is an open source collective of decentralized marketplaces and communities, known as districts. Districts exist as decentralized autonomous organizations on the district0x Network, built upon a standard open source framework comprised of Ethereum smart contracts and front-end libraries. This contract framework provides districts with the core functionalities required to operate an online market or community. Namely, the ability for users to post listings, filter and search through listings, rank peers and amass reputation, and send invoices and collect payments.

We completed a fundraising round in July of 2017, and we're laying the foundation for launching 5 more districts in the coming year. We're dedicated to a long term vision of community driven development and governance. We're committed to making the new technology behind the Ethereum network easy to use for all users. We believe fair and democratic user-owned networks will supplant virtually all centralized marketplaces in existence today. What we build will be free, transparent, and publicly available forever. Come build it with us!

Permalink

Software Engineer - Large scale infrastructure at AdGoji (Full-time)

ABOUT THE JOB:

To support our team, we are looking for an experienced software engineer who is passionate about large scale infrastructure and big data problems. Our infrastructure processes tens of thousands of requests per second and we need to be able to make real-time decisions when targeting mobile advertisement to the right audience. If you have experience with high performance systems (50k QPS and up), then you are the person we are looking for!

RESPONSIBILITIES:

  • Design, code and maintain high-performance, scalable systems on AWS
  • Improve the reliability and efficiency of our core systems
  • Work fluidly with our other talented engineers to define, build, scale,
    and maintain systems.
  • Write code, tools and tests to monitor and automate matters.
  • Troubleshoot, diagnose and resolve issues across the stack (Infrastructure, software, applications and networks.)
  • Value system change and system stability in equal measure.
  • Java Programming experience required, you will work with Clojure code

YOUR PROFILE

Besides living in (or willing to move to) the Amsterdam area, required qualifications include the following must haves:

  • Experience with large scale AWS infrastructure and development
  • Experience with software engineering best practices (e.g. unit testing, code reviews, design documentation)
    • Strong algorithms and data structures background
    • Ability (or willingness to learn) Clojure, our primary language tool
    • BSc, MSc, or PhD in Computer Science or equivalent work experience

TOOLS/LANGUAGES YOU WILL WORK WITH:

Our main software tool is Clojure. Clojure is very practical for many reasons. On the data side it helps us query huge amounts of data which we collect via Kafka. In other occasions the expressiveness and REPL oriented programming helps us to move fast. We run our infrastructure on AWS. Docker and Cloudformation help us to deploy many services like Datomic, ElasticSearch and Riemann, to name a few. We have a scrum-like working process.

Tech Stack: Clojure, Hadoop, AWS, ElasticSearch, Datomic, Riemann, Docker, Onyx, CascaLog, Kafka, CloudFormation.

PERKS:

Work with a team of carefully selected smart and dedicated people.

  • Focus-on-the-future-job: #programmatic #machinelearning #data #mobile
  • Work in an amazing office with crazy inspiring view on 't IJ - River, located close to Central station of Amsterdam.
  • Daily fresh biological lunch, juices, fruits, snacks and unlimited fresh bean - coffee & mint tea.
  • Competitive salary and being part of the steady growth of the company
  • Flexibility: it’s a full-time job, but we’re open to listening to your needs.

Get information on how to apply for this position.

Permalink

a smol comic about clojure






I made this cute comic because I’ve been writing a lot of clojure(/script) and people have been asking me about it so I’ve been introducing it a lot, and also holy crap a friend gifted me a graphics tablet over the weekend and I am finally reunited with digital art aaah :D :D :D

For those following along at home on shitty internet connections or screen readers or are struggling to parse my funky handwriting, I’ve transcribed the comic below!

introducing clojure! (and clojurescript)

(clojure says ♥, and clojurescript says ♥_BANG_ because alas, it has gone through the transpiler).

clojure is a dialect of lisp.

1
2
3
4
5
{ :name "lisp"
:birth 1958
:age 59
:typing [:strong :dynamic]
:favourite-ice-cream "vanilla"}

Cool thing I learned: lisp was the first (non-assembly) self-hosted language (it compiled itself!!)

1
2
3
4
5
{ :name "clojure"
:birth 2007
:age 10
:typing [:strong :dynamic]
:favourite-ice-cream "raspberry cheesecake"}

(here I drew a lisp family tree, except the tree is an octopus)

clojure is a hosted language.

This means it is a symbiote living on the JVM (Java Virtual Machine). Clojure can talk to its host with interop. That means it can use its host’s libraries :D

(here I drew clojure as a mushroom, also a symbiote, whispering sweet interops into the ear of the JVM).

Clojure can target many things! We call it clojurescript when it targets javascript. That means we can write clojure programs that work in the browser :D

(here I drew clojurescript also as a mushroom, lookin pretty chill on its host, javascript, console.log-ing, as one does.)

(I can’t believe I just spent my evening drawing clojure as various mushrooms…)

choosing a text editor to use with clojure seems to be something people think deeply about.

Lots of people like emacs.

I use Atom.

As long as you’ve got something automatically minding your parens (e.g. parinfer or paredit) it’s probably fine. (here I drew a thumbs up, except the thumb is a face, and the face is saying “nice.”)

(extra note: if you decide to use emacs, don’t try to configure it from scratch like I did the first three times I tried to use emacs. go borrow someone else‘s configuration!)

why would anyone use clojure??

  • JVM
    • lots of mature libraries from java
    • JVM abstracts away hardware & OS
  • concurrency
    • clojure was designed for concurrency!
  • lisp
    • lisps are fun to write :D
    • functional programming is an interesting way to think
    • everything is data in clojure, which is a pattern really suited for some tasks
    • macros are powerful and fun!
  • community ♥
    • people are super friendly
    • you can directly talk with a lot of library maintainers and helpful folks in #clojurians slack channel
    • cozy local communities, such as in Berlin (:
    • ClojureBridge!!

what are the problems?

  • it takes a while for your brain to adjust if you are coming from some languages.
  • the toolset and build process was a lot to take in at once (I’m still learning it…)
  • it’ll probably be a while before you’re comfortable enough to harness the full power of the language.
  • it’s really hard to make fan art because there are no animals or puns ):

It’s okay! Just go have fun!

Also I’m super excited because Euroclojure is this week and it’s in Berlin! aaahh see you there?? (if you manage to find me and give me paper I’ll draw you hosting clojure as a mushroom, because I haven’t drawn enough mushrooms this week).

Permalink

Copyright © 2009, Planet Clojure. No rights reserved.
Planet Clojure is maintained by Baishamapayan Ghose.
Clojure and the Clojure logo are Copyright © 2008-2009, Rich Hickey.
Theme by Brajeshwar.