100% Remote Full Stack Clojure Engineer at Lumanu

100% Remote Full Stack Clojure Engineer at Lumanu

Lumanu simplifies how digital content creators do business. Our tools for invoicing, payments, and collaborations streamline inconvenient tasks, freeing content creators to do more of what they love. We support the entire spectrum of creators, from all backgrounds and skill sets including influencers, digital designers, photographers, and brand marketers. By helping them manage their business, Lumanu empowers content creators to live life on their own terms.

Do you have:

  • 2+ years of software experience in: Go, Kotlin, Python, Ruby, Java, Scala, Elixir, Erlang, Rust, Typescript or Clojure

  • Experience w/ Git, Pull requests, CI/CD.

  • Experience as a Manager, Team Lead or individual contributor.

  • Experience collaborating with others and building software in a rapid iterative environment with a deep focus on your customer.

  • Experience building modern responsive web/mobile applications.

  • Knowledge of distributed system design utilizing cloud infrastructure.

  • Aptitude to go deep on complex problems and find quick solutions.

Does this sound like a dream opportunity to learn functional programming and yet you don’t have the experience? This could be your opportunity to finally work in a functional stack, please reach out and share your aptitude to learn and join the Clojure community. ❤️

Read about our $12M Series A, led by Origin Ventures, with participation from Alumni Group, 500 Startups, and Gaingels: https://venturebeat.com/2021/07/28/lumanu-raises-12m-to-simplify-business-for-the-creator-economy/

More About Lumanu

Lumanu builds technology that makes doing business in the Creator Economy easy, collaborative, and fun. With Lumanu, creators can, 1) easily manage, protect, and grow their business, 2) send/receive money instantly while collaborating with brands and other creators, and 3) benefit from a community that’s built to support them in every step of their journey.

Lumanu takes care of business, so creators have the freedom to create, entertain, and inspire.

At Lumanu, we are committed to hiring individuals who share our vision for embracing and celebrating differences. We encourage folks from historically marginalized communities to apply for our opportunities - this includes, but is not limited to, people of color, women, people who identify as LGBTQIA+, people with disabilities, first and second generation immigrants, veterans, and more.


Senior DevOps Engineer

We are looking for a Senior DevOps Engineer to join product development for our client from the USA. The product is an AWS hosted multi-module payment and analytical platform for the healthcare services, written in Clojure/Go language stack. The product encompasses a few applications for customer journeys (web, mobile) and complex micro-service architecture. 


  • Deploy and configure of microservice applications on AWS 
  • Build and improve tools for developers to deploy and troubleshoot applications and infrastructure 
  • Develop and support configuration management code 
  • Develop and support of CI/ CD processes 
  • Support and administration of infrastructures on AWS 
  • Assist in planning and reviewing application architecture and design to promote efficient deployment process  
  • Servers monitoring 


  • 4+ years of experience as a DevOps Engineer
  • Strong AWS knowledge and experience 
  • Experience in using CI/CD automation tools (Jenkins) 
  • Experience with IAC tools like Terraform  
  • Experience in operating a container orchestration cluster (Kubernetes, Docker) 
  • Proficiency in Networking/VPC/Security groups 
  • Familiarity with GitHub 
  • Experience with ChatOps 
  • ElasticSearch knowledge  
  • Scalable architecture skills 
  • Ability to work effectively within a team and with minimal supervision

We offer friendly working conditions with competitive compensation and benefits including:

  • Comfortable working environment
  • Friendly team and management
  • Competitive salary
  • Free English classes
  • Regular performance-based compensation review
  • Flexible working hours
  • 100% paid vacation, 4 weeks per year
  • 100% paid sick-leaves
  • Corporate and team building events

Apply Now 

The post Senior DevOps Engineer first appeared on Agiliway.


How to tame Card based user interfaces

A collection of resource to make less mistakes while building Card based UIs

Photo by Patrik Velich on Unsplash

Cards UI are the notoriously flexible building blocks of every modern application. Their forgiving nature allows us to go wrong and make some mistakes that could have been avoided.

I didn’t realise it until I made those mistakes and referred to Google for ideas. Here’s my goto list of resources:

  1. Simple Design Tips for Crafting Better UI Cards by Nick Babich
  2. Ultimate guide for designing UI cards by Vikalp Kaushik
  3. Card UI design: fundamentals and examples by JUSTINMIND Team
  4. Successful card design in 3 steps: UX, UI, and Framework by Brenna Grey Mickey
  5. 8 rules for a perfect card design by Dorjan Vulaj
  6. Applying a Card-Based Design to User Interfaces: Best Practices by RubyGarage Team

Hope you find it useful !

You might also like:


Stressed Servers

Pushing the limites with Clojure - web servers edition - Writing large scale web applications in Clojure can offer a unique challenge. In this series I'll share and walk through the results of a web servers profiling project I have been working on. My goal? a humble one. Find the best web server in the Clojure ecosystem, and the best...


Clojure Deref (Sept 17, 2021)

Welcome to the Clojure Deref! This is a weekly link/news roundup for the Clojure ecosystem. (@ClojureDeref RSS)


This week we released Clojure 1.11.0-alpha2 which pulls together several things the core team has been working on plus a variety of older bug fixes. I wanted to expand a bit more on some of the items in the release. In general, it’s worth digging into these jira tickets as we expend a fair amount of effort trying to making them good records of problem/alternatives/solution and I’m going to be heavily mining them here.

This was the most voted open request on Ask Clojure and really stemmed from the big increase in qualified keyword usage from spec. In spec you might name a spec :my.cool.domain/account where "my.cool.domain" is not a "real" namespace that can be loaded, it’s just a useful qualifier. You can of course use the full qualifier every time but that can be tedious.

Clojure has long had namespace aliases, most commonly defined using the :require or :use clause of ns. However, both require and use bottom out in load-file, which loads the needed namespace before creating the alias. You can alternately use create-ns to create a runtime Namespace without loading, and then use alias to alias to it, and this has been the most common workaround (sometimes with some macro goo around it to make it easier).

We explored several different options for this, and they’re enumerated in CLJ-2123. We looked at changing alias to automatically create a runtime namespace, but this would change alias semantics, possibly in ways that would impact existing users. We looked at creating a new kind of keyword-only alias (I prototyped this - it was a terrible mess to retain backward portability). We looked at expanding ns to include a variant of alias, but this one would have been a breaking change for the spec (this is kind of a tangent) and we think would have been a bit harder to cover for existing ns analyzers than where we ended up, which was to add a new :as-alias clause to require, that is essentially like :as, but does not require a loaded namespace.

So you can then do:

(ns foo
  (:require [my.cool.domain :as-alias d])) ;; works! (doesn't load)

::d/account ;; valid

The core.specs.alpha spec has been updated to include :as-alias and a new version of that library was built and is depended on by 1.11.0-alpha2. Important to note is that this was an additive (via keys*), not breaking, change.

Also, a highly voted old request, update-keys and update-vals are functions that have been rewritten many, many times in Clojure code bases and utility libraries (also often called map-keys/map-vals). When we look at stuff like this, we try to be clear about what challenges we believe are in or out of scope, how generic to make the implementation, what promises we should make in the docstring, and how to achieve the best performance given that. Other impls may make different choices than we did here, which is fine. For example, should this work on all associative types (like vectors?) or just maps? We decided covering the map case well was more important. There was a lot of perf testing done on implementation choices - that’s not all covered in the tickets.

This is kind of an old ticket, but had a direct impact on testing for update-keys and update-vals, which rely on the IKVReduce protocol. Protocols are an open extension mechanism where choices are made based on type matching (including Java inheritance). The IKVReduce protocol also has an associated Java interface IKVReduce which can be used by Java implementation classes needing to hook into the protocol (similar pattern is used in other places as well inside Clojure’s impl). To cover this, the IKVReduce protocol is extended to both the IKVReduce interface (fast impl) and to the IPersistentMap interface (slow impl). If a concrete impl (like PersistentHashMap) matches multiple types, the "closest" one will match. However, PHM implements both of these and it’s essentially a "tie". What we’ve seen over the years is that based on the ordering of things returned from reflection, it’s possible for PHM to route to either of the two protocol extensions, sometimes leading to much slower results for reduce-kv.

We looked at a bunch of ways to resolve this - tweaks to reduce-kv, special cases for the built-in impls (PHM, PAM), adding a protocol preference system like multimethods have, etc. There are tradeoffs in all these approaches, some pretty significant. In the end we decided that another way to remove the ambiguity is to define the "slow fallback" implementation on Object, rather than on IPersistentMap. This widens the scope of what reduce-kv can be applied to, essentially changing it from "maps" to "colls that seq to map entries". The Object case is always a last resort case, so there is no longer any ambiguity - PHM will always take the "fast" through IKVReduce interface (self reduction). Also, this means that reduce-kv now works on java.util.Maps (another very old jira request) and potentially other useful things. Needless to say, there was a lot of perf testing done on this and several of the alternatives. Along the way, it seemed clear that the "slow" path fallback was a lot slower than it needed to be, so that was also rewritten for better performance. The major tradeoff in the solution we landed on is that (satisfies? IKVReduce x) is now true for everything. As an internal protocol rarely used directly, there is very little code in the wild doing anything like this (xforms is the most notable example we found and we’ve been consulting with Christophe about that one).

The end result of all this is that reduce-kv is faster in the "slow" case, will predictably use the "fast" case when it can, and can be applied to more types of colls.

Other enhancements and bug fixes

  • CLJ-1908 Add clojure.test api run-test and run-test-var to run single test with fixtures and report

  • CLJ-2600 Don’t block realized? of delay on pending result

  • CLJ-2649 Fix order of checks in some-fn and every-pred for 3 predicate case to match other unrollings

  • CLJ-2636 Get rid of reflection on java.util.Properties when defining clojure-version

  • CLJ-2350 Improve keyword arity exception message

  • CLJ-2444 Fix typo in test-vars docstring

  • CLJ-1509 AOT compile more Clojure namespaces

  • CLJ-2387 Fix off-by-one in socket server port validation

We’ve been working on creating some new internal processes for working through jiras, and this is the first chunk of those. We’re hoping to get a mixture of highly voted (important to the community), important from core team perspective, and low-hanging fruit into each 1.11 alpha/beta. I don’t have a prediction for when we will "finish" 1.11 as it depends a lot on what we decide to include, and that is an ongoing discussion.

As always, it’s a huge help to us if you can swap it into your build and just run your test suite to see if anything breaks (or is faster!). We’d love to hear that feedback, even if it’s "all good".

Videos and podcasts

Libraries and Tools

New releases and tools this week:

  • Reveal Pro - Read Eval Visualize Loop for Clojure, Supercharged

  • secrets.clj 1.0.0 - A Clojure library designed to generate cryptographically strong random numbers.

  • build-uber-log4j2-handler v0.1.0 - A conflict handler for log4j2 plugins cache files for the tools.build uber task.

  • build-clj v0.3.0 - Common build tasks abstracted into a library

  • tools.build v0.5.0 - Library of functions to make Clojure builds

  • martian v0.1.18 - The HTTP abstraction library for Clojure/script, supporting Swagger, Schema, re-frame and more

  • clj-kondo 2021.09.15 - A linter for Clojure code that sparks joy

  • julian 1.0.0 - A Clojure(Script) library to convert between Julian Day Number and common time

  • fijit 1.0.7 - A Clojure library for Scala interop

  • holy-lambda 0.5.0 - The extraordinary simple, performant, and extensible custom AWS Lambda runtime for Clojure

  • clojure-exercism-template - Learn more Clojure and Interactive Programming with Exercism in the browser

  • clojure-lsp 2021.09.13-19.32.00 - Language Server (LSP) for Clojure

  • graal-build-time 0.0.11 - Library to initialize Clojure packages at build time with GraalVM native-image

  • https://convex.world/ - Convex is an open, decentralised, and efficient technology platform built in the spirit of the original Internet

  • Tutkain 0.10.0 - A Sublime Text package for interactive Clojure development

  • datalevin 0.5.13 - A simple, fast and versatile Datalog database

  • babashka 0.6.1 - Native, fast starting Clojure interpreter for scripting

  • trenchman v0.3.0 - A standalone nREPL/prepl client written in Go and heavily inspired by Grenchman


Clojurescript Reagent Image-Previewing Selector

Intro It took some elbow-grease but I was able to convert online examples1 into a working image selector in Reagent Clojurescript. It isn’t a lot of code, but there were two complications: converting the declarative style of the examples into more functional CLJS (hint: it involves closures), and doing it in a way that will jive with the React life-cycle. CSS code The following styling makes things look okay. This is using Garden2 syntax.


Free stuff on internet for developers


Bunch of free tutorials, hosting sites, organization tools and some student benefits

Table of contents


In this post, I will list some free stuff that you can get on the internet and that might be useful for you.

I will try to organize them in some categories so you can just skip them if you do not care about them. I just want to point out that I am not affiliated with any of these pages, I just find them interesting and helpful.

So let's start


"Education is the most powerful weapon which you can use to change the world." This quote was said by Nelson Mandela and I think we all can agree with it. We are lucky that we are living in a world where education is very accessible to us through the internet.

I will show you some sites that offer education in computer science or in some specific programming language.


Pluralsight is an education company that offers a variety of video training courses for software developers, IT administrators, and creative professionals through its website. It is a subscription-based site which means that you need to pay money to get access to their videos. They also offer a 10-day free trial. I will show you how can you get one month for free. Pluralsight is good because there are beginner, intermediate, and advanced level topics for some programming languages, frameworks, or tools. They also have those videos grouped in categories called paths. Paths combine specific courses and tools into one experience to teach you any given skill from start to finish. Paths are aligned to an individual's knowledge level, to help you and your team develop the right skills in the right order.

To get Pluralsight for free for one month you just need to go to Visual studio benefits and log in with your Microsoft account. If you don't have a Microsoft account, you can easily create one with any email address. Once you are logged in, you should see this:

As you can see, you also get a free subscription for some Microsoft products and also one month of premium subscription to Linkedin learning.


Udemy is an online learning and teaching marketplace with over 155000 courses and 40 million students. There you can learn programming, marketing, data science, and more.

Every once and then, some courses become free so you can claim them on your Udemy account. To do so, you need to obtain a coupon that gives you a 100% discount.

People post those codes on this subreddit. Just get the code and apply it to the course. Then you can start watching that course. Keep in mind that not all courses are good, so sometimes it is not even worth taking a coupon.

The Odin project

The Odin Project is an open-source online curriculum for learning web development. The curriculum contains programming fundamentals and two career paths you can take. One path is to become full-stack ruby on rails developer and the other is to become a full-stack javascript developer. I would recommend taking the javascript path unless there is plenty amount of ruby on rails jobs in your area.

Free Code Camp

Free code camp is a non-profit organization that consists of an interactive learning web platform, an online community forum, chat rooms, online publications, and local organizations that intend to make learning programming accessible to anyone. The curriculum is mostly focused on web development but there are also parts of the curriculum focused on Python (data analysis, machine learning, and scientific computing).

Free code camp also has a great YouTube channel where they post various programming tutorial videos.

Free Programming Books

Free Programming Books is a list of over 3,000 free programming books and other free programming resources, maintained collaboratively as a repository on Github. With lists in 29 spoken languages, it has helped countless programmers around the world acquire and improve their programming abilities.


edX is an American massive open online course (MOOC) provider created by Harvard and MIT. It hosts online university-level courses in a wide range of disciplines to a worldwide student body, including some courses at no charge.

You can learn about computer science, data science, business, chemistry, medicine, music, and many other topics. You can enroll in courses for free, access materials for a limited time, and only if you want a certificate at the end, you can pay for it.

Game development

I think everybody at least once in their life wanted to create some kind of game. Devga.me is a great starting point. They have a great number of guides, tutorials, free resources, tools and engine recommendations, a YouTube channel, and a Discord community.

Web hosting

If you want to host a personal project, proof of concept, or any non-commercial app, you can do that easily and for free on several web hosting providers.

If you don't have any application to host, then you can create a basic 'Hello world' application written in Java, C#, or any other language you are working with and host it. That way you are getting useful and new experience of putting applications on the server.

'The big three' free tier

(Probably) The three most popular web hosting providers are Amazon, Microsoft, and Google. But they are not just web hosting providers, they offer cloud services. But for now, let's just focus on web hosting. If you want to host a web application, select one of the providers and Google how to do hosting. There are plenty of tutorials explaining step by step how to do that. If you are a web developer, it is good to have some experience with any of the providers because some companies are using cloud services almost on daily basis.

Heroku free tier

Heroku is a cloud platform as a service (PaaS) supporting several programming languages. One of the first cloud platforms, Heroku has been in development since June 2007, when it supported only the Ruby programming language, but now supports Java, Node.js, Scala, Clojure, Python, PHP, and Go out of the box. There is a high chance that you can host any language to Heroku using Docker. They have documentation for every language they support so it should not be hard to have your application up and running.

GitHub pages

If you want to host a website, portfolio, or blog you can do it for free and it is very easy.

All you have to do is:

  • Create or log in to your GitHub account.
  • Create a new repository that is named your_github_username.github.io
  • Add index.html with some content and commit that.
  • In your browser visit your_github_username.github.io. You should see the content of your index.html.

Now you can create a website from scratch using HTML, CSS, and javascript or you can just download a free website template and change text and images.


Being a developer means that most of the day you are sitting in front of a computer. You are using your mind a lot more than your body. This can result in mental exhaustion, stress, and burnout. To prevent or reduce those negative impacts on your mind it is a good idea to organize your days and increase your productivity.


As a developer you get (or take) tasks from issue tracking and project management applications like Jira. But during your workday, you need to do several other things that are not directly connected to your tasks like attend meetings, call or talk with colleagues, review pull requests, onboard new colleagues, etc.

Sometimes you have a lot of tasks like this and they can cause a problem for you. The best idea would be to write them down so you don't need to remember them and then prioritize them. That way you have those tasks in the same place and you resolve them by priority.

Todoist is an application that does that. It allows you to create tasks as a TODO list for every day, set priority on every task, and even sort tasks in projects. When you complete your task just delete it and focus on other tasks.

Note-taking applications

Evernote is an app designed for note-taking, organizing, task management, and archiving. The app allows users to create notes, which can be text, drawings, photographs, audio, or saved web content. Notes are stored in notebooks and can be tagged, annotated, edited, searched, given attachments, and exported. Evernote is cross-platform, for Android, iOS, macOS, and Microsoft Windows. It is free to use with monthly usage limits and offers paid plans for expanded or lifted limits.

Notion is an application that provides components such as notes, databases, kanban boards, wikis, calendars, and reminders. Users can connect these components to create their own systems for knowledge management, note-taking, data management, project management, among others. These components and systems can be used individually, or in collaboration with others.

Applications like these two are useful for taking notes when learning something new, taking meeting notes, creating a draft version of product documentation, etc.

One thing I am using this kind of app for is to keep track of all tasks I worked on, business logic that was required for each task, and sometimes what programming paradigm I used to complete that tasks. This way, when somebody in the future asks me about some feature I worked on or some bug I fixed, I can easily remember why and how it was done. This is very useful when I work on several tasks or event projects in a short time period. It is easier to write that stuff than try to remember it.


If for whatever reason you need to work on or use the computer in the evening it is a good idea to install f.lux. f.lux is an application that removes blue light from your computer screen during the evening hours. Blue light might give you trouble sleeping. According to some researches, blue light suppresses the body's release of melatonin.

f.lux makes your computer screen look like the room you're in, all the time. When the sun sets, it makes your computer look like your indoor lights. In the morning, it makes things look like sunlight again. Once you install it, you'll need to configure it and then you will forget about it. It will do everything automatically.

Student benefits

If you are a university student and you are 'lucky' that your student email address is accepted to these pages then you can use the benefits they offer for students.

GitHub Student Developer Pack

GitHub student developer pack is probably the biggest and most famous pack of benefits for students. They offer free access to some tools and frameworks, credits for web hosting, resources for learning, etc. I am sure that pack will give you enough material to play with and you can use it to increase your skill level, knowledge and boost your portfolio.

JetBrains IDE licenses

JetBrains is a software development company that makes tools for software developers and project managers. The company offers many integrated development environments (IDE) for the programming languages Java, Groovy, Kotlin, Ruby, Python, PHP, C, Objective-C, C++, C#, Go, JavaScript, and SQL. The company created the Kotlin programming language.

For students, they offer free licenses for every IDE for personal use. If you are Java/Spring developer I would recommend their IntelliJ IDE.

It is also worth mentioning JetBrains Academy. JetBrains Academy is an online platform to learn programming, including such programming languages as Python, Java, and Kotlin. Their resources are great because they teach you language from beginner to advanced level.

LinkedIn learning

LinkedIn Learning is a massive open online course provider. It provides video courses taught by industry experts in software, creative, and business skills. You can get access for free by having a library card. To see if your library is eligible, just Google Linkedin learning. If it is, you just need to get a code for the website and you can start learning.

Namecheap domain

Namecheap offers free .me domains and to select universities in the US, UK, Canada, and Australia.

However, if you have access to the GitHub student developer pack then you can claim your domain for sure. While you might not be interested in it, it can be a good idea to try a set up a domain with your website just for the experience of doing it.


In this post, I gave you a lot of resources that you can get for free. Pick whatever you like, do whatever you want, and get some experience. After all, investing in your knowledge is never a wrong idea.


10+ Github Repositories You Should Know as a Developer

Hello, everyone! Today, we'll go through some great repositories that every developer should be aware of.

Following an extensive investigation, I discovered several excellent repositories that might help you grow as a developer; stay tuned as I will be sharing them soon.

1. Web Developer RoadMap

The web developer roadmap repository can find a path for frontend, backend, and dev ops developers. The goal of these roadmaps is to give you a sense of the landscape and help you decide what to learn next if you're stumped. This repository includes three graphs that show you precisely what each path entails and which abilities are required. Frontend, backend, and dev-ops are the paths described in this repository.

GitHub logo kamranahmedse / developer-roadmap

Roadmap to becoming a web developer in 2021

Web Developer Roadmap - 2021

Roadmap to becoming a web developer in 2021

Below you find a set of charts demonstrating the paths that you can take and the technologies that you would want to adopt in order to become a frontend, backend or a devops. I made these charts for an old professor of mine who wanted something to share with his college students to give them a perspective; sharing them here to help the community.

Special Announcement:

We now have a YouTube Channel
I plan on covering the roadmaps and put more content there
Subscribe to the channel.

Purpose of these Roadmaps

The purpose of these roadmaps is to give you an idea about the landscape and to guide you if you are confused about what to learn next and not to encourage you to pick what is hip and trendy. You should grow some understanding of why one tool would be…

2. 30 Seconds of Code

The 30 seconds of code repository is the most popular on this list, with over 65K ratings on GitHub. For all your development needs, this repository contains small JavaScript code snippets.
Calculating Celsius to Fahrenheit and computing weekdays between two dates are among the tidbits. All of these snippets provide solutions to issues that you may encounter while programming in JavaScript.

GitHub logo 30-seconds / 30-seconds-of-code

Short JavaScript code snippets for all your development needs


30 seconds of code

Short JavaScript code snippets for all your development needs

  • Visit our website to view our snippet collection.
  • Use the Search page to find snippets that suit your needs. You can search by name, tag, language or using a snippet's description. Just start typing a term and see what comes up.
  • Browse the JavaScript Snippet collection to see all the snippets in this project or click individual tags at the top of the same page to narrow down your search to a specific tag.
  • Click on each snippet card to view the whole snippet, including code, explanation and examples.
  • You can use the button at the bottom of a snippet card to copy the code to clipboard.
  • If you like the project, give it a star. It means a lot to the people maintaining it.

Want to contribute?

  • If you want to help us improve, take a…

3. Awesome Cheatsheets

Cheatsheets are handy. Cheatsheets are something that every developer has used at least once. Especially when you're studying anything new, such as a programming language or framework, fortunately, you won't have to make your cheatsheets because the incredible cheatsheets library has you covered.

GitHub logo LeCoupa / awesome-cheatsheets

👩‍💻👨‍💻 Awesome cheatsheets for popular programming languages, frameworks and development tools. They include everything you should know in one single file.


Awesome GitHub license

WEBSITE DIRECTORY: Available here.

📚 Awesome cheatsheets for popular programming languages, frameworks and development tools. They include everything you should know in one single file.

🤔 Why Awesome-Cheatsheets?

I usually make a cheat sheet when I want to improve my skills in a programming language, a framework or a development tool. I started doing these kinds of things a long time ago on Gist. To better keep track of the history and to let people contribute, I reorganized all of them into this single repository. Most of the content is coming from official documentation and some books I have read.

Feel free to take a look. You might learn new things. They have been designed to provide a quick way to assess your knowledge and to save you time.

📚 Table of Contents

📃 Languages

View cheatsheets

Command line interface


4. Web Development Resources

This is an excellent project about Web Development resources

GitHub logo markodenic / web-development-resources

Awesome Web Development Resources.

Awesome Web Development Resources Awesome

This is an awesome project about Web Development resources. ⚡

Resources are added frequently! ⚡


If you like this repo, be sure to ⭐ it.

Please read contributing guidelines before submitting new resources.

Initially created by Marko Denic on Twitter.

Table of Contents


⬆ back to top

Learning Platforms:

⬆ back to top

Coding Challenge Platforms:


5. CSS Protips

The CSS protips repository has several valuable hints for improving your CSS skills. We've all experienced how difficult it can be to style a web page from time to time. The suggestions on this page will assist you in resolving issues that you have most likely encountered previously.

6. Awesome Design Pattern

This repository not only covers generic architecture but also includes code examples of specific design patterns. More than ten programming languages and frameworks are represented in these samples. When you need to apply one of the design patterns yourself, these examples come in handy.

GitHub logo DovAmir / awesome-design-patterns

A curated list of software and architecture related design patterns.

Awesome Software and Architectural Design Patterns

PRs Welcome awesome awesome

A curated list of software and architecture related design patterns.

Software design pattern - A general, reusable solution to a commonly occurring problem within a given context in software design. It is a description or template for how to solve a problem that can be used in many different situations.


Programming Language Design Patterns

7. Coding Interview University

It takes a lot more than Googling a list of frequent interview questions to prepare for an interview. So, if you're seeking tools and step-by-step instructions on how to prepare for an interview, this repository is for you. This repository contains a wealth of links and materials to help you understand computer science principles and details.

GitHub logo jwasham / coding-interview-university

A complete computer science study plan to become a software engineer.

Coding Interview University

I originally created this as a short to-do list of study topics for becoming a software engineer but it grew to the large list you see today. After going through this study plan, I got hired as a Software Development Engineer at Amazon You probably won't have to study as much as I did. Anyway, everything you need is here.

I studied about 8-12 hours a day, for several months. This is my story: Why I studied full-time for 8 months for a Google interview

Please Note: You won't need to study as much as I did. I wasted a lot of time on things I didn't need to know. More info about that below. I'll help you get there without wasting your precious time.

The items listed here will prepare you well for a technical interview at just about any software company including the giants:…

8. Awesome Interview Questions

One of the most popular repositories is the excellent interview questions repository. Our is one of the most popular repositories on this list, with around 50K ratings on GitHub. This repository provides a large number of interview questions for nearly every programming language and framework.

9. Free Programming Book

This GitHub repository contains many free learning resources from which you can learn a variety of technical skills. The list used to be on StackOverflow, but it was later transferred to GitHub to make it more maintainable. This repository is available in over 30 languages. The Free Ebook Foundation, a 501(c)(3) non-profit corporation, manages this repository.

GitHub logo EbookFoundation / free-programming-books

📚 Freely available programming books

This page is available as an easy-to-read website at https://ebookfoundation.github.io/.

List of Free Learning Resources In Many Languages Awesome


This list was originally a clone of StackOverflow - List of Freely Available Programming Books with contributions from Karan Bhangui and George Stocker.

The list was moved to GitHub by Victor Felder for collaborative updating and maintenance. It has grown to become one of GitHub's most popular repositories, with 200,000+ stars, 6100+ commits, 1600+ contributors, and 43,000+ forks.

The Free Ebook Foundation now administers the repo, a not-for-profit organization devoted to promoting the creation, distribution, archiving, and sustainability of free ebooks. Donations to the Free Ebook Foundation are tax-deductible in the US.

How To Contribute

Please read CONTRIBUTING. If you're new to GitHub, welcome!

How to Share



Other Languages

10. Command Line

One method is to become familiar with the command line and know how to use it. The art of command line repository provides several tips and tricks that can be useful in specific situations or save time compared to other options. This repository is helpful for both novice and advanced command-line users.

GitHub logo jlevy / the-art-of-command-line

Master the command line, in one page

🌍 ČeštinaDeutschΕλληνικάEnglishEspañolFrançaisIndonesiaItaliano日本語한국어polskiPortuguêsRomânăРусскийSlovenščinaУкраїнська简体中文繁體中文

The Art of Command Line

Note: I'm planning to revise this and looking for a new co-author to help with expanding this into a more comprehensive guide. While it's very popular, it could be broader and a bit deeper. If you like to write and are close to being an expert on this material and willing to consider helping, please drop me a note at josh (0x40) holloway.com. –jlevy, Holloway. Thank you!

curl -s 'https://raw.githubusercontent.com/jlevy/the-art-of-command-line/master/README.md' | egrep -o '\w+' | tr -d '`' | cowsay -W50

Fluency on the command line is a skill often neglected or considered arcane, but it improves your flexibility…

11. Awesome

The fantastic resource contains a wealth of information on various topics related to software development and programming. If you genuinely want to learn something new, it's a one-stop-shop. This repository contains excellent content for various topics, ranging from programming languages to big data, novels, business, and security.

12. FreeCodeCamp

FreeCodeCamp, I'm sure you've heard of it. It is one of the largest and most user-friendly repositories on GitHub. It provides newbies with a free way to learn how to code efficiently. They have a large community and a friendly forum where people can support and improve their coding skills. Bookmark this repo if you want to learn and build something new while collaborating with millions of people.

GitHub logo freeCodeCamp / freeCodeCamp

freeCodeCamp.org's open-source codebase and curriculum. Learn to code for free.

freeCodeCamp.org Social Banner

Pull Requests Welcome first-timers-only Friendly Open Source Helpers Setup Automated Rocket.Chat

freeCodeCamp.org's open-source codebase and curriculum

freeCodeCamp.org is a friendly community where you can learn to code for free. It is run by a donor-supported 501(c)(3) nonprofit to help millions of busy adults transition into tech. Our community has already helped more than 10,000 people get their first developer job.

Our full-stack web development and machine learning curriculum is completely free and self-paced. We have thousands of interactive coding challenges to help you expand your skills.

Table of Contents


freeCodeCamp.org offers several free developer certifications. Each of these certifications involves building 5 required web app projects, along with hundreds of optional coding challenges to help you prepare for those projects. We estimate that each certification will take a beginner programmer around 300 hours to earn.

Each of these 50…

13. Frontend Development

Resources for frontend web developers that have been manually curated.

GitHub logo dypsilon / frontend-dev-bookmarks

Manually curated collection of resources for frontend web developers.

Frontend Development Awesome

Manually curated collection of resources for frontend web developers.

You are viewing a browseable version, split by category in many small files. There is also a really huge file with every single resource on one page. Proceed to the totally gigantic file if you are into this kind of thing.

This is the current version, which receives ongoing updates. If you want the good old bookmarks, please use the tag v.1.0. Keep in mind, that the old version has many outdated links.

frontend.directory Gitter Twitter


The outward or visible aspect of a website.

  • Animation: The process of creating motion and shape change.
  • Typography: The style, arrangement, or appearance of typeset matter.
  • Visualization: Placing data in a visual context.


High level structure of the frontend code and the discipline of creating such structures.

  • Algorithms: A self-contained step-by-step set of operations to be performed. Algorithms perform calculation…

14. Tech Interview Handbook

For busy engineers, selected interview preparation tools.

GitHub logo yangshun / tech-interview-handbook

💯 Curated interview preparation materials for busy engineers

Tech Interview Handbook

Get paid more. Moonchaser has negotiated hundreds of tech offers. Get 1-1 guidance from their experienced team of ex-FAANG PMs, SWEs, and Recruiters. Find out more

What is this?

No one has time to do a few hundred LeetCode questions. Here's free and curated technical interview preparation materials for busy engineers, brought to you by the author of the Blind 75 List.

Besides the usual algorithm questions, other awesome stuff includes:

I hope you find these resources helpful 😊

I'd love to connect with you at Twitter | LinkedIn | GitHub

See you in my next blog article. Take care!!!


40: Shipping Clojure code with Paulus Esterhazy

Paulus Esterhazy talks about trunk-based development, monorepos, path-focused design, and fast feedback. Pitch clojureD 2020: “Angels Singing: Writing for Programmers” by Paulus Esterhazy Monorepos and the Fallacy of Scale Trunk based development GeePaw Hill Path-Focused Design DORA Metrics to Measure DevOps Performance The RAT: Rework Avoidance Theory Understanding Incremental Switchover bhauman/devcards juxt/bidi BurntSushi/ripgrep


Clojure Engineer (Film Industry) at Gower St

Clojure Engineer (Film Industry) at Gower St

gbp50000 - gbp65000

At Gower Street Analytics we are transforming the Film industry using predictive analytics and data science. We have contracts with major studios and cinema chains who use our product to inform their planning and releases.

We are currently hiring a mid-level or senior developer in a UK based remote role with experience in Clojure or functional programming in general. You'll be part of a small dev and data science team with responsibilities ranging from changes to our ETL pipeline to frontend features.

Here's a few things we think set Gower St apart:

  • Flexibility: If working 3 or 4 days per week instead of full time suits you better, then we can make that happen.
  • Inclusivity: Gower St strives to be an inclusive and diverse workplace. Empathy and Integrity are amongst our core values, and we are thoughtful about how we build consensus and come to decisions.
  • Remote done right: We've been a remote organisation long before Covid and tend to think we're pretty good at making that work for all of us.
  • Opportunity: You'll have plenty of opportunity to work across teams to define new features and deliver them end to end. We're a small company (~ 20 people), and you'll have lots of opportunities to take on new responsibilities and make a lasting impact on the film industry in this job.


  • Eligibility to work in the UK: This is a UK-based role and candidates must be able to provide documentation to prove that they are eligible to live and work in the UK.
  • Experience: You have past experience of taking end-to-end ownership of system-wide features and you can point to examples where you have been personally responsible for delivering technically challenging work with substantive business value. At Gower St, you'll be working in Clojure, Go, Javascript (Node.js) and Python using Docker and Terraform. You don't need concrete experience in all of these languages for the role, but we value candidates who have experience across multiple languages.
  • Learning and collaboration: Our team members are active learners who collaborate on problems and welcome questions. We expect you to be able to show examples of how you've worked with others to expand your knowledge of a business problem and build consensus across teams.
  • Self-directed: You are comfortable self-managing and working remotely. We prefer if you can point to experience of working in a remote or partially remote role and give us examples that show your initiative and ownership outside of the expectation of your role.
  • Integrity & Empathy: You are thoughtful in your interactions and mindful of how you impact other people through the way you communicate and behave. We expect you to be able to give examples of situations where you've consciously made sure to be inclusive.


  • Flexibility: We are open to you working 3 or 4 days per week and setting your own schedule as long as you're responsive and able to attend important meetings.
  • Compensation: You will earn competitive market salaries for on-site roles, even though we’re fully remote.
  • Holidays & Insurance: You will get five weeks off per year plus bank holidays as well as private health insurance.
  • Conferences: We aim for you to attend one “big” and one “small” technical conference each year.


ClojureScript. Amplified.

"… we're going to build a web app with storage, authentication and everything …"

But how?

My favorite building blocks 🤩

I have tried out some tools that I find very useful. As you may have guessed, the code is developed with ClojureScript. A language I appreciate more each day. Developing an app, without the Interactive REPL? That would be taking a huge step backwards.

I have found that Material-UI works really well in the development of the app I'm working on. The components library cover many usage scenarios, it is well documented and there's a lot of code examples to learn from.

Recently, I added Storybook and really like the idea of developing user interfaces according to Component Driven Design. It reminds me of how I experiment with code using Test Driven Development. Just like TDD, I think tools like Storybook and Devcards changes the way we develop, to the better. Start small & build quality in.

Let's begin with a building block from my favorites list: AWS Amplify.

A basic setup for AWS Amplify & ClojureScript

The official AWS Amplify documentation is all about JavaScript. In this post, and in this example code repo, you will find a ClojureScript setup that I think will get you up & running quickly. First, set up AWS Amplify by following the first parts of the Official getting started guide. You will be creating an AWS account and installing a CLI to initialize your setup.

If want more details, have a look at Hey Webpack, Hey ClojureScript. It's a post describing a ClojureScript & Amplify specific setup that is used in the example repo.

Start coding, but where? 🤔

A pitfall might be where to place the auto generated client code from Amplify. I usually put files like the aws-exports.js at the same level as the root namespace.

In the example code repo, the ClojureScript source code lives in the src/main folder. That's also where I've added the aws-exports.js file.

Configure Amplify in the init function of your app.

Login & Logout with ClojureScript & the Amplify CLI

Adding authentication can easily be done by using the Amplify CLI.

From the docs:

"... The Amplify CLI supports configuring many different Authentication and Authorization workflows, including simple and advanced configurations of the login options, triggering Lambda functions during different lifecycle events, and administrative actions which you can optionally expose to your applications ..."

Use the Auth features in Amplify UI

There's a very useful Higher-Order React Component (aka HOC) in the AWS Amplify UI Library, that will render login and signup views.

I've chosen this less-lines-of-code approach by using the withAuthenticator HOC. To customize things like signup fields or styling, there is also a fully customizable Authorization component available in the Amplify UI library. Or you can use your own components.

The views entry point.
The passed in component is wrapped in the withAuthenticator HOC.

If you already have browsed the code in my example repo, you may have noticed the Reagent reactify-component and as-element functions. These functions are needed when passing components between ClojureScript and JavaScript.

Read more about React Components, elements and instances and how the interop is done with Reagent.

Create, read, update and delete

So far, we have used built in features that will render UI views and handle all auth communication with a backend service. To store, read and update data, we can use the Amplify API feature. Use the CLI to create a backend:

I have chosen GraphQL in my example code, but there's also a REST API option. When using GraphQL, all you need to do is to define data models. Amplify will create the backend infrastructure according to your models. In a matter of minutes, there are AWS AppSync endpoints & DynamoDB tables created for your app.


Here's a GraphQL model. An authenticated user should be able to add data to the profile, like a summary or an "About me" text. The user will be able to create, delete and update the data in the profile. Other authenticated users can read the data when they visit the user's profile.

The schema files belongs to the backend, and lives in the amplify folder of your repo.

async ClojureScript

The Amplify Client Library handles the communication with the backend services. All calls are asynchronous. In ClojureScript, you can use core.async. I haven't yet dig into the core.async stuff, so I'm using Promises here. I think it's a quite straight forward approach.

The data going through the wire is JSON. To make the developer experience better, I think it might be a good idea to add conversion functions to-and-from Clojure data structures. Like this one, converting user settings JSON to Clojure data:

Read more about the ^js type hints in ClojureScript.

Finally: Ship it! 🚢

Here's an excerpt from an amplify.yml that defines the build steps. If you add a definition file in your repo, AWS Amplify will use it in the CI/CD process.

This is the amplify.yml that I use in my example code repo.

There's more details at the official AWS docs about build settings and about amazon-linux-install.

Add UI building blocks to the amplified app

Now we have our amplified ClojureScript app. Let's add UI building blocks from Material-UI, a library that is very popular in the JavaScript & React ecosystem. Here, I'm using it via a ClojureScript library called reagent-material-ui. The library makes it possible to write components using Clojure data structures. You can read more about Material-UI and ClojureScript in my previous post Material Design in a Functional World.

Totally unnecessary css styling used here, but why not?

Testing the UI building blocks with ✨ Storybook ✨

I find Storybook very useful when experimenting with components and user interfaces in isolation. Being able to focus on one specific thing. There's many different aspects of developing an app, and it is sometimes difficult to handle all of them at the same time.

Storybook is a place for trying out things like css, styling, different viewports and UI events. You won't try out the AWS Amplify code here. The Interactive REPL is a better tool for that.

You'll find more about Storybook in Component Driven ClojureScript with Storybook.

Finally, check out my GitHub repo for ideas on how to create apps with the building blocks AWS Amplify, Material-UI, Storybook and ClojureScript.

That's a combination I'd like to call ✨ClojureScript. Amplified. ✨

Top photo by Drew Patrick Miller on Unsplash


Material Design in a Functional World

"... Material is a design system created by Google to help teams build high-quality digital experiences for Android, iOS, Flutter, and the web ..."
from material.io

ClojureScript & React is A 💕 Story

With Clojure, you can write functional & minimalistic code. With ClojureScript and Reagent, you can write functional & minimalistic React components. By adding re-frame to it, we also have a powerful way of handling state changes and triggering events.

The code you write in ClojureScript is instantly compiled to JavaScript React components that runs in your browser. The entire JavaScript ecosystem is available with this kind of setup.

"... React components for faster and easier web development. ..."
from material-ui.com


Material-UI is a very popular React framework. And we can use it with ClojureScript. But the JavaScript interop can sometimes be bit of a hassle. Fortunately, there is a great ClojureScript library called reagent-material-ui that simplifies this a lot.

One thing to notice is that the Material-UI components use React Hooks heavily to inject styling and theming into components. This is something to think about when using Reagent. Basically, just use the functional component syntax [:f> my-component] and you’re all good.

Have a look at the reagent-material-ui docs about common pitfalls in the React/Reagent interop and a fully working example in this GitHub repo.

Storybook: a playground for components

Here’s me playing around with the Card component, using ClojureScript and Storybook. I describe the Storybook integration in detail in this post.

The source code is available at GitHub.

No copy-paste?

I guess it can be a bit overwhelming for a Clojure developer to look at example code from the Material-UI site, with JavaScript/JSX syntax that is quite verbose (you’ll be even more overwhelmed by the TypeScript examples).

A JavaScript developer would probably copy-paste the example code and make some adjustments. We can’t do that. But it is worth the effort writing the code from scratch when discovering that the result is way more simplistic than the original. The amount of code written is usually half the size of the original JavaScript code. Yeah, that’s Clojure!

ClojureScript to the left, JavaScript to the right. Less is more.

Check out my GitHub repo with examples on how you can implement Material-UI components in ClojureScript, with hooks and styles - while having fun writing functional code.

Top photo by Thierry Lemaitre on Unsplash


in which not everything is static, but most things are

The Fennel programming language recently celebrated its fifth birthday, and we ran a survey to learn more about the community and what has been working well and what hasn't. Fennel's approach has always been one of simplicity; not just in the conceptual footprint of the language, but in reducing dependencies and moving parts, and using on a runtime that fits in under 200kb. In order to reflect this, the Fennel web site is hosted as static files on the same Apache-backed shared hosting account I've been using for this blog since 2005.

Of course, generating HTML from lisp code is one of the oldest tricks in the book[1], so I won't bore anyone with the details there. But what happens when you want to mix in something that isn't completely static, like this survey? Well, that's where it gets interesting.

I put the shotgun in an Adidas bag and padded it out with four pairs of tennis socks, not my style at all, but that was what I was aiming for: If they think you're crude, go technical; if they think you're technical, go crude. I'm a very technical boy. So I decided to get as crude as possible. These days, though, you have to be pretty technical before you can even aspire to crudeness.[2]

When I was in school, I learned how to write and deploy Ruby web programs. The easiest way to get that set up was using CGI. A CGI script is just a process which is launched by the web server in such a way that the request comes in on stdin and environment variables and the response is sent over stdout. But larger Ruby programs tended to have very slow boot times, which didn't fit very well with CGI's model of launching a process afresh for every request that came in, and eventually other models replaced CGI. Most people regard CGI as somewhat outmoded and obsolete, but it fits Fennel's ethos nicely and complements a mostly-static-files approach.

So the survey generates an HTML form in a static file which points to a CGI script as its action. The CGI script looks like this, but it gets compiled to Lua as part of the deploy process to keep the dependencies light.

(let [contents (io.read "*all")
      date (io.popen "date --rfc-3339=ns")
      id (: (date:read "*a") :sub 1 -2)]
  (with-open [raw (io.open (.. "responses/" id ".raw") :w)]
    (raw:write contents))
  (print "status: 301 redirect")
  (print "Location: /survey/thanks.html\n"))

As you can see, all this does is read the request body using io.read, create a file with the current timestamp as the filename (we shell out to date because the built-in os.time function lacks subsecond resolution) and prints out a canned response redirecting the browser to another static HTML page. We could have printed HTML for the response body, but why complicate things?

At this point we're all set as far as gathering data goes. But what do we do with these responses? Well, a typical approach would be to write them to a database rather than the filesystem, and to create another script which reads from the database whenever it gets an HTTP request and emits HTML which summarizes the results. You could certainly do this in Fennel using nginx and its postgres module, but it didn't feel like a good fit for this. A database has a lot of moving parts and complex features around consistency during concurrent writes which are simply astronomically unlikely[3] to happen in this case.

At this point I think it's time to take a look at the Makefile:

upload: index.html save.cgi thanks.html 2021.html
    rsync -rAv $^ fennel-lang.org:fennel-lang.org/survey/

index.html: survey.fnl questions.fnl
    ../fennel/fennel --add-fennel-path "../?.fnl" $< > $@

save.cgi: save.fnl
    echo "#!/usr/bin/env lua" > $@
    ../fennel/fennel --compile $< >> $@
    chmod 755 $@

    rsync -rA fennel-lang.org:fennel-lang.org/survey/responses/ responses/

2021.html: summary.fnl chart.fnl questions.fnl responses/* commentary/2021/*
    ../fennel/fennel --add-fennel-path "../?.fnl" $< > $@

So the pull target takes all the raw response files from the server and brings them into my local checkout of the web site on my laptop. The 2021.html target runs the summary.fnl script locally to read thru all the responses, parse them, aggregate them, and emit static HTML containing inline SVG charts. Then the upload task puts the output back on the server. Here's the code which takes that raw form data from the CGI script and turns it into a data structure[4]:

(fn parse [contents] ; for form-encoded data
  (fn decode [str] (str:gsub "%%(%x%x)" (fn [v] (string.char (tonumber v 16)))))
  (let [out {}]
    (each [k v (contents:gmatch "([^&=]+)=([^&=]+)")]
      (let [key (decode (k:gsub "+" " "))]
        (when (not (. out key))
          (tset out key []))
        (table.insert (. out key) (pick-values 1 (decode (v:gsub "+" " "))))))

The final piece I want to mention is the charts in the survey results. I wasn't sure how I'd visualize the results, but I had some experience writing SVG from my programmatically generated keyboard cases I had constructed on my laser cutter. If you've never looked closely at SVG before, it's a lot more accessible than you might expect. This code takes the data from the previous function after it's been aggregated by response count and emits a bar chart with counts for each response. Here's an example of one of the charts; inspect the source to see how it looks if you're curious:

Linux-based (43) MacOS (11) Windows (6) Other BSD-based (4) Linux-based: 43, MacOS: 11, Windows: 6, Other BSD-based: 4

I had never tried putting SVG directly into HTML before, but I found you can just embed an <svg> element like any other. The <desc> elements even allow it to be read by a screen reader.

(fn bar-rect [answer count i]
  (let [width (* count 10)
        y (* 21 (- i 1))]
    [:g {:class :bar}
     [:rect {: width :height 20 : y}]
     [:text {:x (+ 5 width) :y (+ y 12) :dy "0.35em"}
      (.. answer " (" count ")")]]))

(fn bar [i data ?sorter]
  ;; by default, sort in descending order of count of responses, but
  ;; allow sorting to be overridden, for example with the age question
  ;; the answers should be ordered by the age, not response count.
  (fn count-sorter [k1 k2]
    (let [v1 (. data k1) v2 (. data k2)]
      (if (= v1 v2) (< k1 k2) (< v2 v1))))
  (let [sorter (or ?sorter count-sorter)
        answers (doto (icollect [k (pairs data)] k) (table.sort sorter))
        svg [:svg {:class :chart :role :img
                   :aria-label "bar graph" :aria-describedby (.. "desc-" i)
                   :width 900 :height (* 21 (+ 1 (length answers)))}]
        descs []]
    (each [i answer (ipairs answers)]
      (table.insert svg (bar-rect answer (. data answer) i))
      (table.insert descs (.. answer ": " (. data answer))))
    (table.insert svg [:desc {:id (.. "desc-" i)} (table.concat descs ", ")])

{: bar}

In the end, other than the actual questions of the survey, all the code clocked in at just over 200 lines. If you're curious to read thru the whole thing you can find it in the survey/ subdirectory of the fennel-lang.org repository.

As you can see from reading the results, one of the things people wanted to see more of with Fennel was some detailed example code. So hopefully this helps with that, and people can learn both about how the code is put together and the unusual approach to building it out.

[1] In fact, the HTML generator code which is used for Fennel's web site was written in 2018 at the first FennelConf.

[2] from Johnny Mnemonic by William Gibson

[3] If we had used os.time with its second-level granularity instead of date with nanosecond precision then concurrent conflicting writes would have moved from astronomically unlikely to merely very, very unlikely, with the remote possibility of two responses overwriting each other if they arrived within the same second. We had fifty responses over a period of 12 days, so this never came close to happening, but in other contexts it could have, so choose your data storage mechanism to fit the problem at hand.

[4] This code is actually taken from the code I wrote a couple years ago to handle signups for FennelConf 2019. If I wrote it today I would have made it use the accumulate or collect macros.


Tests are living documentation

Tests can serve many purposes.

You might write tests as a way of driving the design of your software. Other tests might be written in response to a discovered bug and, if written first, those tests you know when you’ve fixed the bug and act as guardrails preventing the reintroduction of that bug. Tests can also be used to confirm you haven’t changed behavior while refactoring.

Tests can also be used as documentation. Unlike non-executable documentation, tests will always match the implementation’s behavior.

An example in a comment or other documentation deserves to be in a test. Take the following sketch of a Clojure function:

(defn confobulate
  "Takes a string and transforms it to the confobulated form. Examples:
  - \"alice\" -> \"EcilA\"
  - \"//yolo1\" -> \"//oneOloY\"
  (-> s
      ;; insert some work here, not going to implement this

The docstring has examples in it to aid humans in understanding its behavior. These examples are useful! But they stop being useful and start being dangerous when they stop being accurate.

We can use unit tests to keep examples like this correct. You can write comments near the assertions letting future readers know about the documentation that needs to be updated if behavior changes.

(deftest confobulate-should-ignore-slashes
  ;; If this assertion changes the docstring needs to be updated
  (is (= "//oneOloY" (confobulate "//yolo1"))))

(deftest confobulate-reverses-and-capitalizes
  ;; If this assertion changes the docstring needs to be updated
  (is (= "alice" (confobulate "EcilA"))))

Any example in a comment or other non-executable documentation should be an assertion in a unit test. You’ve already taken the time to document the behavior; take the time to figure out how to document it in a way that will fail if the behavior changes.


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.