Clojure guards

Once I wanted to have something like a pretty “match” operator from Scala (or Rust, or C# 7), but in Clojure. In this blog I explore some solutions for that available in Clojure world.

Use case

Generally, you would use pattern matching as a neat syntax for multiple if..else or switch..case statements. Consider this example of transforming values between two enums:

if (entityType == DBEntityType::ISSUE) {
    return UIEntityType::ISSUE;
} else if (entityType == DBEntityType::SUBTASK) {
    return UIEntityType::SUBTASK;
} else {
    return UIEntityType::UNKNOWN;
}

This could be written neatly with a switch..case statement:

switch (entityType) {
    case DBEntityType::ISSUE:
        return UIEntityType::ISSUE;
    case DBEntityType::SUBTASK:
        return UIEntityType::SUBTASK;
    default:
        return UIEntityType::UNKNOWN;
}

In C# starting with version 7 you could write this using switch expression:

return entityType switch {
    DBEntityType.ISSUE => UIEntityType.ISSUE,
    DBEntityType.SUBTASK => UIEntityType.SUBTASK,
    _ => UIEntityType.UNKNOWN
};

But what if you have multiple conditions to check?

if (entityType == DBEntityType::ISSUE && permissions.canEdit(user, DBEntityType::ISSUE)) {
    return UIEntityType::ISSUE;
} else if (entityType == DBEntityType::SUBTASK && permissions.canEdit(user, DBEntityType::SUBTASK)) {
    return UIEntityType::SUBTASK;
} else {
    return UIEntityType::UNKNOWN;
}

This can not be converted to switch..case nicely. But with switch expressions (or rather, pattern matching, in general) you can do something like this:

return entityType switch {
    DBEntityType::ISSUE when permissions.canEdit(user, DBEntityType::ISSUE) => UIEntityType::ISSUE,
    DBEntityType::SUBTASK when permissions.canEdit(user, DBEntityType::SUBTASK) => UIEntityType::SUBTASK,
    _ => UIEntityType::UNKNOWN,
};

Using cond

;; Note how this method does not check the `n > 3` case
(defn testFn [n]
    (cond
        (= n 1) "You entered 1!"
        (= n 2) "You entered two!"
        (= n 3) "You entered three!"
        :else "You entered a big number!"
    ))

(defn complexFn [entityType user permissions]
    (cond
        (and (= entityType :db-issue) (can-edit? permissions user :db-issue) :ui-issue)
        (and (= entityType :db-subtask) (can-edit? permissions user :db-subtask) :ui-subtask)
        :else :ui-unknown))

Using condp

;; Note how this method does not check the `n > 3` case
(defn testFn [n]
    (condp = n
        1 "You entered 1!"
        2 "You entered two!"
        3 "You entered three!"
        "You entered a big number!"))

(defn complexFn [entityType user permissions]
    (condp = [ entityType true ]
        [ :db-issue (can-edit? permissions user :db-issue) ] :ui-issue
        [ :db-subtask (can-edit? permissions user :db-subtask) ] :ui-subtask
        :ui-unknown))

Using guard macro

(defn generateGuardBody
    "Generates the function body required to support the guard macro"
    [args]
    (let [[thisBranch remainingBranches] (split-at 2 args)
            testCond (first thisBranch)
            testResult (second thisBranch)
            elseFunc (if (empty? remainingBranches)
                false
                (if (=  1 (count remainingBranches))
                    (first remainingBranches)
                    (generateGuardBody remainingBranches)))]
        `(if ~testCond
            ~testResult
            ~elseFunc)))

(defmacro defguardfn
    "Creates a haskell-style guarded function"
    [fnName args & body]
    `(defn ~fnName ~args
        ~(generateGuardBody body)))

(defmacro guard
    "Allows inline guard syntax without surrounding defn"
    [& body]
    `~(generateGuardBody body))


(defguardfn testFn [n]
    (= 1 n) "You entered 1!"
    (= 2 n) "You entered two!"
    (= 3 n) "You entered three!"
    (> n 3) "You entered a big number!")

(println (testFn 5))

(defguardfn fib [n]
    (< n 2) n
    (+ (fib (- n 1)) (fib (- n 2))))


(defn testFn-2 [x]
    (guard
        (= x 1) "One!"
        (= x 2) "Two!"
        true  "Something Else!"))

(println (map fib (range 0 10)))
(println (testFn-2 3)) ; "Something else!"

Using multimethods

;; Implementing factorial using multimethods Note that factorial-like function
;; is best implemented using `recur` which enables tail-call optimization to avoid
;; a stack overflow error. This is a only a demonstration of clojure's multimethod

;; identity form returns the same value passed
(defmulti factorial identity)

(defmethod factorial 0 [_]  1)
(defmethod factorial :default [num]
    (* num (factorial (dec num))))

(factorial 0) ; => 1
(factorial 1) ; => 1
(factorial 3) ; => 6
(factorial 7) ; => 5040

Using core.match

(defn div3? [x] (zero? (rem x 3)))
(let [y [2 3 4 5]]
  (match [y]
    [[_ (a :guard even?) _ _]] :a0
    [[_ (b :guard [odd? div3?]) _ _]] :a1))

(let [x [1 2 3]]
  (match [x]
    [[1 (:or 3 4) 3]] :a0
    [[1 (:or 2 3) 3]] :a1))
;=> :a1

(let [x {:a 3}]
  (match [x]
    [{:a (:or 1 2)}] :a0
    [{:a (:or 3 4)}] :a1))
;=> :a1

(let [v [[1 2]]]
  (match [v]
    [[[3 1]]] :a0
    [[([1 a] :as b)]] [:a1 a b]))
;=> [:a1 2 [1 2]]

Big O notation

The best big O notation explanation I’ve ever saw I’ve found on… Google Play Market! I was hanging around, looking for the suggested software and, for some reason, I’ve decided to install some educational application for programmers. And here’s what I’ve found…

Read more

Chicken in Blender

This is a chicken. This 3D model I’ve made in 3.5 hrs in Blender (with texturing).

Taking into account the fact I’ve started learning Unity 3D, I will possibly use this in the remake of my old Shoot Them! game. Like this (early preview, made with Unity 3D in ~3 hrs):

Two sides of web application. Part 2: sketching

General architecture

The first thing we need to think of is how we’ll be gathering the information about users. It’s quite easy - we just need to get a request from a visitor. Of any kind - it may be a request to get an image, a file, a stylesheet or a script.

Then we’ll just parse headers from that request and save the extracted data in the database. The only problem here is: how to get unique key from each request?. We may use visitor’s IP address. It’s the easiest way.

Read more

Two sides of web application. Part 3: Communication Layer

Foreword

In this section we will implement the communication layer for our application. It’ll handle all the requests to/from our web server. Have no worries - we will create server application in the next section!

First resource

Let’s create a Session resource. Since we have no backend part, we should stub the data. We’ll use Angular Services. That’s easy: a service defines a function, returning, say, an object. That object will be used every time you call a service. And you may use not only objects - you may return functions, constants or literally anything from your services.

Read more

Irrlicht Newton GD tutorial: finishing the first scene

If you remember, we ended our coding excercises at place, where we almost created our first Newtonian body, but we did not actually have enough models.

We discussed collision shapes a bit. So let’s create one for our brand new model!

We have a nice ramp to work with. But how we can reconstruct the same shape in the terms of Newton? Newton offers a set of collision shapes for us:

  • Sphere

    Sphere
  • Box

    Box
  • Cone

    Cone
  • Capsule

    Capsule
  • Cylinder

    Cylinder
  • Chamfer Cylinder

    Chamfer Cylinder
  • Convex Hull

    Convex Hull
  • Trimesh

    Trimesh

Obviously, not sphere, cone, capsule, nor cylinder make sense for us. We could use box shape, but then we simply ignore our inner faces (inside walls):

Box collision shape for our ramp

A bit better, but still the same situation with convex hull shape:

Convex hull collision shape for our ramp

Generally, the way we create our Newtonian body is:

  1. create collision shape
  2. create blank Newtonian body
  3. set body properties like collision shape, mass, inertia parameters, etc.
  4. store the pointer to the graphical entity for that body in the userData property

And then Newton Game Dynamics will take your body into account when processing other objects in the NewtonWorld.

Read more

Irrlicht Newton GD tutorial: making simple level with Blender

In this section we will have short but powerful introduction to Blender. We will cover just enough of model creation basics, you will need to create most of simple projects.

No, we will not cover animation, shaders or modificators here, but just enough minimum to create this ramp floor for our tutorial:

The desired result

You will find lot of keyboard shortcuts here. And this is one of the most awesome features of Blender - you can work without menus or panels! Everything you need can be done with keyboard!

So let’s dive in Blender now!

Read more

End-to-end testing with WebdriverIO

Small intro

Have you ever heard about end-to-end testing? Or maybe about testing automation? Those of you who had, may now be imaging Selenium. That’s right, in most of cases you will need to run Selenium Server and use Selenium Webdriver in your tests. Those come handy to run a standalone browser window, with no caches, filled-in fields or cookies and perform some operations in it.

In this article I will tell you my story of writing E2E tests for Angular webapp.

A brief of history

In my case, we first tried to use Protractor with Chai.js. That time we ended up with almost unsupportable bunch of code, succeeding in 100% of runs.

Next time we eliminated Chai and reworked all our tests to use Protractor only. So the code became more clear (I did not like the syntax, but it worked…), but after upgrading libraries (including Protractor), the ratio of successfull test runs decreased to just 40%.

We worked for two days, trying to fix those tests. And that’s how webdriverio came to our project.

And here’s a short tutorial on how to implement E2E tests with webdriverio in a sample project.

Read more

Loooong lists with Clojure

Whaaaaat?

These days I was given a reeeeally interesting homework at the university. I was given a set of MD5 hashes, calculated from single words (taken from Libre Office’ dictionaries) with a given sault. And the task was to find all those words.

So, the first idea which came to my mind was using an internet service for MD5 breaking. But… aaarrrggghhh! There’s a sault, so the webservice, looking for words over a dictionary fails to find mines…

So the second idea was to take that dictionary from Libre Office and iterate through it. At the end, it worked =) And worked reeeally fast. But that is not an interesting part.

I wandered if I could find those words in my dictionary, generated by my own code.

Read more

Custom logging with timbre

Timbre?

At my job we recently started researching logging tools to make our RESTful API, written in Clojure, writing logs in JSON format. We were using Log4j already, but decided to use another tool for this task, making it less painful. So we felt into timbre. Is seemed so easy to use, but it is really undocumented.

According to timbre’s API, we needed to define our own appender for writing to a custom JSON file. And we found the output-fn option to configure this behaviour. But it is not documented at all, so we started looking for repositories, using timbre, examples and all the stuff. And finally, we ended up with our own solution.

Underneath you will find description of our way to use timbre from scratch.

Read more