RSSAmplifier

Blog

Daw-Ran Liou's website

dawranliou.comRSS feed ↗53 posts

Latest posts

The Cost of Code Quality

I recently came across Peter Taoussanis 's London Clojurians talk - Some controversial truths , resonated with me a lot. It's funny that I wouldn't be ready for this talk two years ago (and I'd probably dismissed the ideas immediately and called it heresy). As I spent more and more time in the software industry, I'm finally ready for this talk. Similar ideas had been brewing in my mind for the…

Defaulting to Transducers

Transducers are great. I've been defaulting to write transducers as opposed to the lazy-seq operations for the past two years at work. To me, transducers are better building blocks to compose Clojure programs for their many benefits that come with reasonable drawbacks/obstacles. And, you know what, though I don't always like recommending people to do things one way or another: you should default…

Intermediate Developer

This is a story of an average intermediate software developer. Being an intermediate developer, I cared a lot about my code. I spent a fair share of time weighing the pros and cons of my approaches to solving problems. Is this code too clever to be understood? Are there hidden invariants that weren't being explained? How easy is the code to be changed in the future? How aesthetic is the code,…

Don't kill my xref buffers

I like buffers. When I first started using Emacs, I used to feel paranoid about keeping too many buffers. Nowadays, I don't even notice the hundreds or thousands of buffers buried in Emacs. I like xref . The built-in package, xref , is an essential part of my workflow at Kira Systems (now acquired by Litera). We use a monorepo setup for our flagship Machine Learning contract analysis SaaS product…

Vanilla ClojureScript

The vanilla ClojureScript app we'll be building throughout the article Introduction When I started writing ClojureScript apps, I was introduced to many tooling that jointly contributed to this fantastic reloadable workflow that was unmatched by anything I knew. I had recently read several ClojureScript-specific questions from both Clojure newcomers and experienced JVM Clojure developers. It…

Advise Eglot to Support Clojure Monorepo Setup

Updates 2022-03-28: A Better Solution Since I published the original solution, I've found certain things were not working as I claimed. There's a better solution, which is mentioned shortly in this section, without hacking Emacs lisp code. Because my intent to write this article is less about giving you the solution but more about demonstrating a way to tweak Emacs' package to fit your own…

I, too, Wrote Myself a Static Site Generator

You can view the source code here . Story My history of playing with static site generator starts with Jekyll, Pelican, Hugo, Middleman, and eventually landed on Zola , which is my personal favourite among these off-the-shelf static site generators. 1 There were very little things to complain about Zola, but one major painpoint was that - it isn’t built on Clojure (or any Lisp) so I didn’t know…

Compiling Emacs from Source on MacOS Big Sur

Recently I started to compile the Emacs master branch from source for daily use instead of using one of the popular formulas on Homebrew. 1 It’s pretty cool to try the latest features like the native compilation and the native emoji before the stable releases. Also it’s quite a satisfying experience to be able to compile Emacs from source. It took me several tries to get it right but I think I…

Structural editing in vanilla Emacs

Strict structural editing Last time I switched from the lispy / lispyville combo for structural editing s-expressions to paredit for its simplicity. However, I started to realize that I kept unbinding commands from the paredit-mode-map such as C-d , C-k because they were unnecessarily restraining. Quote from this reddit thread : I tend to think that all of the slurping, burping, gurgling,…

Back to paredit

To simplify my s-exp workflow I had been using lispy and lispyville for general s-expression editing and navigation previously. My setup works pretty well, but I often found the packages are a bit of a feature bloat. Plus, I don’t use most of the transitive dependencies (ace-window, counsel, ivy, swiper, hydra). Over time, I started to realize what I like or want and what I don’t care about for my…

My personal experience to learn Clojure and Emacs together

I recently made a bit lengthy response in the Clojureverse discussion on the topic “GNU Emacs + Cider vs VS Code + Calva” . To summarize: I recommend learning Emacs. I recommend learning Emacs and Clojure at the same time. It’s going to be very challenging and fun and rewarding. Quote: Hi, I just want to provide another data point here. I started learning Clojure using my own free time back in…

Implementing an Event-Driven ClojureScript mini-framework with core.async

This was my experiment of re-implementing a lighter version of the popular ClojureScript front-end framework, re-frame , for the purpose of studying.[^1] A demo project of the result can be found here - mini-reframe . In the project README, you can see the section “Self-guided source code tour” if you like to read the code. In this post, I’d walk you through the steps of implementing it from…

Better performance with Java arrays in Clojure

I was working on re-implementing the Stochastic gradient descent algorithm in Clojure based on the blog post How to Implement Linear Regression From Scratch in Python . Because I wasn’t happy about the performance when the dataset is in the order of thousands rows of thousands features, so I started looking into ways to go lower-level to use the Java arrays and found this amazing article on…

Entering Spring Lisp Game Jam 2021

From the Spring Lisp Game Jam 2021 site: Lisp Game Jam is a bi-annual game jam taking place for a full 10 days. After the jam has finished, 3 days are given to everyone to try out the game submissions and vote for their favorites. My goal coming into this Game Jam was to finish a playable game. No matter how burnout I felt at the end, I was quite happy to finish the game using just my own free…

On Personal Websites

Hi everyone! I want to share some of my thoughts and the benefits of building personal websites. This won’t be a step-by-step guide to building your first personal website. It’ll take me to write another article for it. Instead, hopefully, I can convince you to build a personal website. Here we go. Learning the technologies Building a personal website is a great learning exercise for the…

Clojure higher-order functions explained: complement

Checkout the index for the full series. Source code Here’s the source of complement in clojure 1.10.1 : (defn complement "Takes a fn f and returns a fn that takes the same arguments as f, has the same effects, if any, and returns the opposite truth value." {:added "1.0" :static true} [f] (fn ([] (not (f))) ([x] (not (f x))) ([x y] (not (f x y))) ([x y & zs] (not (apply f x y zs))))) Usages From…

The distinction between Reagent component and React component

At work, I rarely have to think about the distinction between a Reagent component and a React component since Reagent does such a good job providing a coherent and simple API to use. (Plus, we don’t use any extern JS component libraries.) I came across the StackOverflow question the other day. While researching for the answer, it occurred to me that the simplicity of Reagent API can sometimes…

Clojure higher-order functions explained: fnil

Checkout the index for the full series. Source code It’s better to read the source code first because source code don’t lie. Here’s the source of fnil in clojure 1.10.1 : (defn fnil "Takes a function f, and returns a function that calls f, replacing a nil first argument to f with the supplied value x. Higher arity versions can replace arguments in the second and third positions (y, z). Note that…

The Biggest Positive for Emacs

I came across the interview with Henrik Lissner , the creator of Doom Emacs, and it really resonated with me about the biggest positive for Emacs (starting at 48:37 ): The biggest positive for Emacs, hands down (that addresses all its negatives) is self-documenting, which primarily means documentation is a first-class citizen in ELisp. You can easily look it up any variable, function, macro, face,…

Clojure higher-order functions explained: index

Besides all the other amazing things Clojure enables, I just want to take a moment to appreciate Clojure being a functional programming language that offers many higher-order functions out of the box great for daily tasks. Although the usage of higher-order functions could sometimes lead to too much cleverness in the code, and arguably bad for readability (apologies to my colleagues), it’s really…

Clojure nil busting one-liners

TL;DR To remove all nil s from a seq: (remove nil? xs) To transform a seq and remove nil s from its result: (keep a-transform xs) To replace all nil s with a fallback value from a seq: (map (fnil identity a-fallback) xs) Preface nil is a value in Clojure that represents “the absence of a value”. Working with nil s is quite common in Clojure. Most of the core library functions deal with nil s…

On Learning Emacs

Classical learning curves for some common editors Classical learning curves for some common editors I once came across a Tweet telling people how to use Emacs like this: step 1, download Emacs; step 2, spend the next 10 years configuring it. At first, this seems pretty silly, yet, there are some truths in it. I, for one, didn’t spend 10 years before becoming comfortable using Emacs as my daily…

My Emacs Clojure Development Environment Overview

Preface To me, Emacs isn’t a text editor but rather an extremely flexible development environment that allows anyone to optimize their workflow. I used to be a Vim user and did everything inside the terminal: Vim for code editing, bash commands for running/testing code, and git cli for all other git operations. I wasn’t in any sense a Vim superuser. However, I felt pretty comfortable to do most of…

Rewriting My Emacs Config

Since the last post, I had switched over to Doom Emacs for a while and then, hopefully, have switched back to my hand-crafted emacs config for the last time. I wanted to try Doom for some reasons: I didn’t like the startup time of my previous handcrafted emacs config, I found painful to look at my emacs config, and I wanted to learn more from this very successful community-driven project. Even…

Rethink Syntax Highlighting

Update 2021-02-28: My color themes are now released ! Check it out! A screenshot of my current editor theme - sketch-white I’m a minimalist when it comes to how I like to highlight my code - my code editor is usually almost monochromatic, just black, white, three shades of gray, and an accent color like orange. If those colors sounds a lot to you, I have to assume you either are an extreme…

From Vim to Emacs

I was a Vim user a couple years back. I totally loved (and still love) the philosophy of Vim as well as the hjkl navigation. In contrast, Emacs didn’t make any sense to me. C-v for page down and M-v for page up? Does that even make any sense to anyone? Yet here I am, after all those years, writing this article on my Emacs with all the keybinding craziness. I must confess, I enjoy Emacs quite a…

Think rationally, talk emotionally

The current state of my mind was greatly influenced by John Locke (洛克) and Empiricism (經驗主義). In contrast to René Descartes’s (笛卡爾) Rationalism (理性主義) where human have innate ideas, philosopher and physician John Locke believes that knowledge is instead “determined only by experience derived from sense perception.” This is also known as Empiricism. The ideas we learned in the early days would have…

My Core Values

I’ve never tried to verbalize my core values before, though it feels right to do so for the first time in 30 years of my life. I hope this post serves the right place for the future me to reflect on. This post is an open letter to my future self. You might find many ancient Chinese wisdom influences below, which says a lot about my origin. Balance The Chinese idiom, “物極必反,” means “Things will…

Domain Exploring with Clojure Spec

I read a great article “ Domain modelling with clojure.spec ” by Adam Bard and started to use more clojure.spec for domain modeling. Here I want to share my process, which I called “Domain Exploring.” It really is just a combination of REPL-driven development with domain modeling in it’s essence. Domain Modeling vs Exploring From Wikipedia - Domain Model : In software engineering, a domain model…

Re-frame Effects VS Coeffects

When I first started using re-frame , I was a bit confused about what effects and coeffects are, or, what fx s and cofx s are. They both seemed to relate to the “Side Effects” (or “Effects”) functional programmers dislike. It was hard for me to distinguish them. Before you read on, if you’ve never came across re-frame’s official documentation or the cljdoc page , please start there. They are…

How I built Bex

In this article, I’d like to share with you the technologies and services that I use to create Bex . If you are, and I assume you are, a programmer, Bex is simply a personal online markdown text editor. TL;DR Site: Hugo + vanilla JS, deployed to Netlify App: ClojureScript , Re-frame , Shadow CLJS , also deployed to Netlify Authentication and database: Firebase Payment: Stripe + Netlify Functions…

Inspect Java Objects with Clojure

The more I work with Clojure, the more frustration I found to work with Java objects. Mostly, it feels an unnecessary process to go through the class definition to find the getter methods to access the data I want, especially when the data is buried under multiple layers of classes deep. In this article, I’ll explain a recipe to create a graphical inspector UI to explore Java objects, frustration…

Tachyons CSS Framework / Library Review

I’ve tried to learn many CSS frameworks (Bootstrap, Foundation, and Bulmar) over the years. They never really clicked and styling felt just as painful as ever. But this has changed since I learned about Tachyons . First introduced by Martin Klepsch (thanks Martin!), I learned and started to use Tachyons since late 2018 for the Cljdoc.org project [1]. This is the only CSS framework / library that…

Interop legacy Java project with Clojure

Recently I got the chance to work on a new feature for our existing Java project. The feature itself is a project that set out to be a general-purpose asynchronous data logging library that can be used company-wide, shared with other projects. I was very into Clojure these days. Learning Clojure has this side effect of mutating your brain to view programming difference. At the meanwhile changing…

Recap 2018

After reading Brandon Sanderson’s State of the Sanderson 2018 and Fogus’s The best things and stuff of 2018 , I feel like to write up a quick summary my year of 2018, a part for myself, and a part for the reason I’ll explain later in the post. Some Numbers in 2018 280 Open Source Software contributions 11.9K Total viewership over the 5 articles I published on Medium 40 Books read Highlights 1.…

Decode your phone number with Clojure

The original article was shared on my Medium The inspiration of this article came from the Cousera course, Functional Programming in Scala. I basically translate the Scala program in section 6 into the Clojure version you’re about to see. Kudos to Martin Odersky. You might have seen ads with interesting phone numbers like: 1–800-FLOWER, 1–800-FREE-411, or 1–800-GOT-JUNK. Those are called…

What is it like to start a study group at work

Have you ever had the feeling that you got so passionate about something that you have to share it to everyone around you? You gotta force people to be passionate about it, am I right? I was so thrilled about Python two years ago, on the day I finally understood what list comprehension is. I had never knew programming could be so… enjoyable. Gradually from chit-chatting with colleagues, to going…

Don’t think. Just write the code!

Imaging you are given a brand new web project, some vague requirements, and a ton of freedom to choose the technical stacks, will you take it? My answer while a couple of months back was… “Hell yeah!” Even though I had never really worked on a real-world project except the blog app that was taught a thousand times from online tutorials. It had been a wonderful journey, with struggles, of course. I…

Composing namedtuple from namedtuples

The problem: One namedtuples is great, two better. But how do I combine the two namedtuples to get the best nametuple of all? For example, how to combine the Square class with Color class? Square = namedtuple('Square', 'x0 y0 x1 y1') Color = namedtuple('Color', 'r g b') # The opposite of DRY principle - WET (we enjoy typing) principle ColoredSquare = namedtupe('ColoredSquare', 'x0 y0 x1 y1 r g b')…

Writing descriptors in Python 3.6+

Special thanks to Luciano Ramalho . I learned most of the knowledge about descriptors from his workshop in PyBay 2017 Have you seen this code or maybe have written code like this? from sqlalchemy import Column, Integer, String class User(Base): id = Column(Integer, primary_key=True) name = Column(String) This code snippet partially comes from the tutorial of a popular ORM package called SQLAlchemy…

Getting Started with Python Internals

This article is a summary of what I learned from Philip Guo ’s CPython internals: A ten-hour codewalk through the Python interpreter source code . I highly recommend you to go through his course. He go through great materials in his videos. You can think of this article as a companion text version of his course, so you can come back for your own references. The only major difference between Philip…

Closures bind late

“Closure is a turtle carrying its shell,” my favorite explanation to closures, quote by Raymond Hettinger . With closures, lots of great features are possible in Python like higher order functions and decorators. I came across this StackOverflow post - How can I return a function that uses the value of a variable? , which helped me bridging the gap in my knowledge, the gap that I sort-of…

Generator - The Basics

I’ve been wanting to write articles about generators for quite some time. Generator is definitely one of my favorite features in Python. Ever since I stopped treating Python like other programming languages, e.g. Java or C++, I start having so much fun writing codes. Unlike other very powerful features (decorators, context managers, or classes) that I sometimes abused a lot, Generators don’t ever…

40 Books I Read in 2016

I challenged myself to read 10 books this year and I ended up reading 40 of them. Phew. What a great year, 2016! I really picked up this new-found hobbit of reading. Feel free to add me friends on Goodread to see which book I’m currently reading. Let’s read more! Here’s my top 5 picks in 2016: Mistborn: The Final Empire (#33) Soft Skills - The Software Developer’s Life Manual (#2) The 4-hour Work…

You probably don't need for loops

Originally titled “Never Write For-loops again” This is a challenge. I challenge you to avoid writing for-loops in every scenario. Also, I challenge you to find the scenarios that are so freaking hard to write anything else but a for-loop. Please share your findings. I’d like to hear about them. It’s been a while since I started exploring the amazing language features in Python. At the beginning,…

Twitter scraper tutorial with Python: Requests, BeautifulSoup, and Selenium - Part 2

This is the part 2 of my Twitter scraper tutorial. If you haven’t checkout part 1, the link is right here. In the last part, I left the tutorial with an unsolved problem — how to scrape the web page that uses infinite scrolling design? Two solutions came into my mind: one more sophisticated, the other more naive: The more sophisticated approach In this approach, you need to understand how the…

Twitter scraper tutorial with Python: Requests, BeautifulSoup, and Selenium - Part 1

Inspired by Bruce, my friend’s take-home interview question, I started this bite-size project to play around with some of the most popular PyPI packages: Requests, BeautifulSoup, and Selenium. In this tutorial, I’ll show you the step-by-step process of how I build a Twitter Search web scraper without using their REST API. “Well, why not use their API?” you might ask. I have two reasons: Not all…

Completed my first hackathon!

It was such a amazing experience. There’s no such thing that make you, and your teammate pull a all-nighter and still gives you one of the best times of your life, except hackathon. (Hackathon rocks!) I want to share with you what it was like, if you don’t already know, and some thoughts about it. My company started its first ever hackathon last Thursday at 8 am. All submission were done on…

Practical Uses of Python AND and OR Boolean Operators

In my previous post — Python Truth Value Testing is Awesome, I mentioned about the sweet combo of the truth value testing and the boolean operators, and gave an example for it using the or-operator. One of my colleagues gave me a comment that the or-operator all seems legit, but the and-operator seems pretty anti-intuitive. This raise the question in me: is there any practical example of using the…

Python Truth Value Testing is Awesome

I’m constantly amazed by the simplicity and readability Python provides. (See The Zen of Python .) As the industry evolves, more and more codes written each day, how to read code fast is a rising question every developer would face. Imaging the times when you faced a new code base and need to ramp up the knowledge in order to work with it. Lot’s of reading, isn’t it? This is why I think Python is…