Hi, I'm Pavel!
And this is my story of how I first met Clojure
Hi, I'm Pavel!
___________
And this is my story of how I first met Clojure
ABOUT ME
Clojure explorer
3
JS & React lover
1
Best dancer at corporate parties
2
Guitar riffs guru
4

EL prólogo

Hi, my name is Pasha (aka Pavel, aka Pablo, aka Paul, and so on) and, to be honest, there is nothing extraordinary in my prequel to Clojure Trek.

I'm a JavaScript developer with 2+ years of experience. 6 months ago I first met Clojure and it hooked me. In a short time, I received an offer to retrain from JS developer to Clojurist. And so the story began!

I was learning Clojure step by step in my free time during this half of a year. I tried to complete different tasks and write test projects to dive deeper into language, and today I want to share my impressions with you.

SYNTAX

Sure, the first thing that caught my eye was unusual syntax.

I was already superficially familiar with Assembler, C#, C++, Pascal, Visual Basic, Python, Java, JavaScript, but Clojure was something I've never encountered before. Unless I saw something similar during the history of programming languages lessons at university. But honestly, I didn't imagine that someone would use these kinds of things today!

The first strong impression was… )))))))))))))). I thought, "What cheerful and smiling people are functional programmers!". My brain was looking for function names but couldn't find them. Later, I found out that the first argument enclosed in parentheses is a function name (set-mood :surprised).
It took a while to adapt to the new Clojure world (at that time I was still actively working on a JS-based project). It was like, you're seemingly used to it and think that you'll never have to do something like:

  • (a + b) ; clojure
  • [a b c] // js (where are the commas...)
  • foo() ; clojure
  • if … // js
Over time, this became less but sometimes my hands still failed me.

Sure, the most useful thing was practice. Especially challenging tasks, where you are thinking about the code logic. Thoughts about syntax recede into the background and 'operate' on a subconscious level.

The first thing I did after studying minimum Clojure basics was to write a program rendering the Mandelbrot set in HTML5 canvas. Not perfect, not at all idiomatically. But it helped me dive deeper into language and get used to it.

Data Types

Clojure data types that stand out for me as the most interesting and curious are the following:

  • :keywords

  • symbols ;I didn't immediately understand how it might come in handy, but it became clear later

  • 1/2 ; it's unusual to see rational fractions, but I thought that it would be very helpful for calculations without loss of precision

Clojure Collections and Code-as-Data

The first thing I wanted to learn was how to create and modify datasets.

I really enjoyed the huge number of functions to work with collections in the standard Clojure library clojure.core. Clojure collections offer interesting juxtaposition, they can act as functions.
({:interesting "to use a map as function"} :interesting)

Generally, using the clojure.core functions reminded me of Lodash, a JS library. For example,
    _(_.range(10)) //js + lodash
        .map(x => x + 1)
        .map(x => console.log(x) || x)
        .map(x => x * x)
        .filter(x => x % 2 === 0)
        .take(3)
        .value()
    
    (->> (range) ;clojure
         (map inc)
         (map (some-fn println identity))
         (map #(* % %))
         (filter even?)
         (take 3))
    
    In both variants, was implemented the logic of lazy collections. Therefore, the calculations involve values from 1 to 6 only and there is no point in going on any further because the answer (4 16 36) has already been received.

    Some things in work with collections were quite puzzling and unusual. For example, I was constantly confused between list and vector.

    Code-as-Data is a concept implemented in Clojure and I'd been looking for it for a long time.

    I've always been very interested in creating my own data constructs, own DSP because it might be handy in describing program logic. Clojure allows you to do something similar using macros:
      (defmacro say [& code]
        (let [words (map str code)
              message (if (= (first words) "that")
                        (next words)
                        words)]
          `(clojure.string/join " " '~message)))
      (say that i am very happy) ;”i am very happy”
      (say macroses are cool) ;”macroses are cool”
      
      
      In truth, this concept isn't easy to assimilate. It takes time and practice to understand how it works and understand the complete process of what happens at runtime and compile time.

      But 'Code-as-data' is precisely one of the reasons why I fell in love with Clojure and why I have no more questions and no complaints about syntax and forest of parens.))))

        ClojureScript

        JS features and Clojure's elegance is a perfect combo.

        I've developed quite a lot in React, so, first of all, when I discovered ClojureScript I went to try Reagent right there.

        I can say that there is no dissonance, hiccup-syntax is very convenient, and most key React features are usable from Reagent.

          Other

          Right away I thought that lack of variables would be a big problem, but as it turned out, that wasn't the case at all.

          After analyzing my JavaScript code, I realized that, in fact, we used mutable operations not so often. Instead of it, usually, we save intermediate results in const variables and use them in other functions. However, in some cases, we use let variables in JS (which are mutated in the cases of calculations in loops) but they also can be replaced by reduce or recursion.

          Speaking of frontend, data persisting requires using state management tools that are quite similar to Clojure's Atoms or Re-frame events.

          Finally, asynchrony. After first reading about asynchrony, сoncurrency, and parallelism in Clojure, it seemed to be very difficult. But some time later, after better understanding, everything fell into place.

          I also noticed that most cases (at least, what came across to me) cover Clojure core.async channels usage.

            EL Epílogo

            Diving into Clojure seemed to be very soft. Every time I encountered something unusual I managed to find some kind of analogy or similarity and adapt to it.

            Language is really beautiful. With its help, it's possible to write some things much shorter and more readable compared to other programming languages.

            Unfortunately, I found few well-structured and complex sources for learning Clojure. Many libraries are scattered all over the Internet (often they duplicate each other partially or completely). There is no handy source to find the most optimal solution quickly. So let's raise the Clojure community together, and along with this, the language infrastructure.

            P. S.: I don't think that I am experienced enough to advise something, but anyway here you can check some sources I used while I was starting with Clojure:

              What happens after you fill this form?
              • Our representative will contact you within one business day

              • We sign an NDA to keep your ideas confidential

              • You share essential requirements with us

              • Our analysts and developers estimate the budget and timeline
              Shall we discuss your idea?
              THE MOST popular POSTS