Ashton Kemerling

AK

Lucid: A Review

Disclaimer: I am not a doctor, and this is not medical advice.

Sleep. We all need it, and very few of us are getting enough of it. Hectic lives, work, children, poor diets, bright screens, and insufficient exercise often result in very poor sleep for those few hours that we are actually in bed. The result is a whole nation of people driving and working while sleep deprived, resulting in car crashes, low productivity, and general negative health outcomes.

Side note: Did you know that people who are sleep deprived are more likely to crave carbs and overeat? Just saying.

None of these things are changing soon; jobs aren’t becoming less hectic and screens certainly aren’t becoming more rare. We all know that we need to improve our diets and exercise more, but very few of us are actually doing it. So what’s to be done for the poor sleep deprived worker?

While most Americans would reach for drugs to fall asleep, I think supplementation is a far better answer. For the past two months I’ve been using Lucid, a supplement from Totem Nutrition, and it has radically altered my sleeping habits.

First off, what’s the difference between a drug and a supplement? Legal definitions non-withstanding, I use the following definition: a supplement is composed of naturally occurring or extracted compounds, while a drug is a new creation that’s completely new to the human body. I’m not one of those people who think that all-natural is the same as safe, since nature manages to produce some pretty poisonous stuff on its own. What I do believe is that well vetted supplements tend to be far more gentle and free from side effects than legal prescription drugs. That’s been my experience at least.

Okay, back to Lucid. So what in the heck is it? Well it’s a sleep aid, a supplement that’s designed to help you fall asleep faster and sleep better. It comes in a liquid form in a dropper bottle, and you’re supposed to hold it under your tongue for about a minute before you go to bed. I really like supplements that come in liquid form, because they’re far easier to adjust the dosing on. For me, half a droppers worth of Lucid does the trick.

You might be tempted to compare it to drugs like Ambien, but how they work is basically completely different. Ambien is a sedative, it literally knocks you out. This might beat laying awake staring at your ceiling, but it has not been shown to improve sleep quality. Also, it increases your risk of doing something silly like hopping into your car naked and crashing it into your neighbor’s house.

Rather than forcing your body to sleep, Lucid is designed to help your body through the entire sleep process. It contains the basic ingredients your body can consume in order to sleep deeply and recover from your day.

First of all, this supplement actually contains a few different supplements I’ve used on and off over the years. Melatonin (you’ve heard of this right?), Velvet Antler Extract, and Colostrum. I’ll go over what these are and why I’ve used them before in a bit. Your body knows how to use these to make you sleep, among other things, but it won’t overuse them. Example: Lucid contains the pre-cursor compounds for testosterone. If you’re running short on this vital hormone, and yes ladies need it too, then your body can use these compounds to make more. But if you’re not running low on testosterone your body won’t overdo it, so no it won’t turn you into Dolph Lundgren or anything, sorry.

Subjectively, I’ve noticed that Lucid has helped me sleep better and wake up better. I spend a lot less time in the morning trying to wake up enough to get dressed and make coffee since I’ve started taking Lucid. I’ve also noticed a marked reduction in tossing and turning, as well as the minor aches and pains that I pick up from the gym. I typically haven’t struggled to fall asleep, so I can’t comment on how Lucid helps me there.

Objectively, I’ve been tracking my sleep via the lovely AutoSleep app for my Apple Watch. I’ve noticed two different things since taking it.

First of all, taking Lucid has comfortably added 30 minutes to an hour of “Deep Sleep” to my nightly statistics, take a look at a control night and a night with lucid. I’ve also noticed fewer incidents of waking up in the middle of the night, and my sleep data shows that I’m more consistently asleep. Well, except for when the cats start crying and biting me for breakfast early. Nothing short of a serious sedative could keep me asleep through that.

More shockingly is what it does combined with alcohol. Alcohol is not good for your sleep, even if it does knock you out quickly. On nights where I drank and forgot my Lucid (hey, nobody is perfect) I averaged a miserable 15-30 minutes of deep sleep. On nights where I drank and remembered my Lucid I got anywhere from an hour and a half to two hours of deep sleep, which is pretty close to a regular night of sleep. Look, I’m not saying that Lucid is a hangover cure, but I am definitely saying that it helped.

Cool, so what’s in it?

  • Melatonin - To help you get sleep.
  • Velvet Bean - Prevents a sleep hangover.
  • Vitamin B6 - Energy & Mood enhancer.
  • Colostrum - Growth factors & immune booster
  • Velvet Antler Extract (VAE) - Pure magic.
  • Water - Duh
  • Alcohol - To protect some of the more fragile ingredients.

Velvet Antler is the one I’m most interested in. I have very fragile tendons in my wrists because of a genetic mutation I have, and statistically 1/3rd of you reading this share that mutation with me. These tendons always get sore from working out, and can strain extremely easily. I’ve had to miss close to a year’s worth of gym time because of injuries to this part of my body. The only thing that got me back to training was cryotherapy, I’ll talk about that another time, and Velvet Antler Extract.

So why don’t I just take it alone? Well, I could, but taking VAE as part of my sleep routine is awesome. First of all, it’s one less supplement to take daily, and that’s great. Secondly I have to take Lucid at night, no point in making myself drowsy at lunch, which means that I get a dose of VAE right before my body does its best repair work: at night. And did I mention that I like getting a good’s night sleep? What’s not to love?

Anyways, I highly recommend that you give Lucid a try. A bottle lasts me about a month or so, and for me it’s a good deal to ensure a great night’s sleep.

Totem Nutrition, the makers of Lucid have been generous enough to offer my readers a 10% discount for trying out Lucid. Use the code “ASHTON2018” for 10% off your first order through the end of 2018.

No, You Probably Don’t Need a Blockchain

On Bitcoins and Blockchains

Oh Bitcoin, the darling of everyone’s economic dreams. Some think it’ll destroy the fed, others hope it’ll kill off the big banks. Some just think it’s going to make them rich, others go as far as hoping it’ll kill off governments completely. Whatever you happen to hate, Bitcoin is coming to destroy it!

All of this is complete nonsense, of course. There are enough mutually exclusive dreams about Bitcoin that it’s clear that not all of them can come true, possibly even the hopes of easy riches given its unpredictable volatility.

But even if you don’t buy into the dream of buying bitcoins to turn them into Lambos or whatever, chances are you are hearing from every single corner that Bitcoin isn’t the future, it’s the blockchain! This refrain has been said so many times that even Bitcoin skeptics feel the need to mention that the blockchain will change the world, even if they don’t think that Bitcoin itself will. That this refrain becomes louder whenever Bitcoin is dropping vs. USD doesn’t seem to worry that many people.

I personally think all of this blockchain stuff is bunk. I am extremely skeptical that the blockchain is indeed the future, and if there will be any future uses for it I don’t think we’ve seen it yet. What we have seen instead is a ton of hype and not a small amount of straight up fraud, which I find worrying.

A Pesky Disclaimer.

First of all, I am not a financial adviser. If you take any of this as advice as far as what to buy or sell, both of us will be very sad. Well, you probably will be sad, I will be annoyed if you bug me about it. If you want legit financial advise, go find an actual financial adviser and pay them.

Secondly, predicting the future is hard. While I am confident that I have not seen any uses for the technologies discussed yet, I am not foolish enough to think that there is a 0% chance that one ever will. I will lay out why I think it’s unlikely, but only time will tell.

So, What is a Blockchain Anyways?

A blockchain is a way of recording a series of transactions in a publicly visible and immutable way. Individual transactions are created with private encryption keys, and then bundled into blocks. Each block is then publicly verified against some sort of algorithm, typically one that involves a lot of computational power to get done. Each verified block contains a reference to the previous block, thus creating a chain of blocks, or a blockchain. The idea is that blocks are very expensive to create, but very cheap to check. If you wish to check the balance or history of a given bitcoin address (“wallet”), then you merely need to scroll backwards through all the blocks and check for any transaction that references that address.

The basic idea is that the verification of any transaction is essentially trustless, there doesn’t need to be any central authority to provide the record of any transaction. All you need is a copy of the blockchain in order to verify any past transaction, should you wish to do so. If you wish to do any transaction on the blockchain, all you need is a copy of the private key for a given wallet. These can be stored in a variety of ways in software or hardware. The people verifying blocks will facilitate your transaction without you or them knowing who each other is.

So, Why the Talk of Blockchains Instead of Bitcoin?

Because Bitcoin uses a blockchain, but it isn’t the blockchain. A blockchain effectively consists of the rules of the chain, the current chain, and all the participants in it. The chain itself is the combination of the starting block, and the longest accepted chain of transactions. This is why there are so-called altcoins, which are blockchain currencies that use slightly different rules or a different initial starting block from the blockchain.

More interestingly still are cases where sections of a blockchain decide that a specific block was invalid, either for security or political reasons. These create a so-called hard fork, where two competing blockchains exist that share a large section of their history. A good example of this is the ever controversial Bitcoin Cash, which was created to overcome perceived deficiencies in Bitcoin itself. If you owned Bitcoin before the fork in August of 2017, then you now own an equal amount of Bitcoin and Bitcoin Cash. Whether or not you think this is economically sound is up to you.

So, Why Don’t You Like Blockchains?

I think blockchains are a novel combination of existing technologies, what I am not convinced of is their long term utility. While it’s been fun to watch a speculative bubble from around cryptocurrencies and their related companies, to my eyes most attempts to expand the blockchain beyond that bubble strike me as foolish at best.

Immutability Woes

Blockchains are by their very design immutable. Barring extreme measures, any transaction entered into them is permanent and irreversible. For financial systems this has a lot of obvious drawbacks: fraudulent or mistaken transactions cannot be undone. Ebay purchaser did not deliver? Tough. Someone held you hostage until you sent them bitcoin? Tough. Private key hacked, or hard drive destroyed? That’s unfortunate for you. The only way to recover bad bitcoin transactions is to convince everyone to do a hard fork, and needless to say that the bar for that is very very high.

But that’s just finance, what about industry? It turns out, that there’s very few systems that truly benefit from an inability to amend or update transactions. Humans bungle input into computers all the time, there’s a whole sector of the economy (customer service) designed to help deal with that. But in an immutable system, it is literally impossible to undo anything written to the blocks. The only possible way to somewhat reverse a bad transaction is to literally make the inverse transaction the next time around, which would involve convincing the opposite party to cooperate. This would rapidly clutter up the chain full of “oops” transactions, which would pretty quickly make you wonder why you’re bothering at all.

That Pesky Real World Thing

One of the most common proposed usages of blockchain is to track the shipment of real world goods, including everything from food to diamonds. On the surface this sounds great, you could easily and trustlessly prove that the shiny rock in your beloved’s ring wasn’t mined by children in a war torn region, fantastic!

The problem is that computers are not the real world. Currently blockchains have a very hard time affecting even digital systems that are not on the blockchain, which is why centralized exchanges exist to facilitate buying bitcoin with USD/EUR/etc. Actually trying to make computers in general reflect the real world is a very hard task, and the blockchain does nothing to solve this issue.

Imagine that you are a blood diamond distributor. You know that rich westerners love diamonds, but feel a bit bad about children being hurt and killed to mine these conflict diamonds. You have a huge incentive to simply lie to the computer to create a fraudulent paper trail for these diamonds, thus generating a higher market value for them. There’s nothing about the blockchain that prevents humans from lying or mistakenly entering the wrong values, and the immutable nature of blockchains makes the cost of mistakes oh so much higher.

Don’t bother thinking about secure hardware at verified locations. At its heart blockchains only require a password to operate, as once you have the private key you can create transactions trivially. If media pirates can extract decryption keys from BluRay players, I guarantee you that diamond smugglers will be able to figure this out too. Once the hardware is in the attackers hands, it is only a matter of time until they strip it down to extract the keys.

The only way around this is to have a trusted neutral party verifying that goods come from exactly where they claim to be from. Not only does this fly in the face of the “trustless” idea above, but handing said employee the ability to create immutable “this diamond is legit” records puts that employee in way more danger than need be. There’s literally nothing about this system that’s superior to what we already have.

Power & Motivation

Blockchains typically use the “Proof of Work” system, where multiple participants try to solve a difficult problem in order to certify a block to be valid. The problem is hard to prevent one person from controlling too much of the mining (computational) pool. This is one of the reasons why Bitcoin itself currently consumes roughly as much power as Delaware while processing about 4 transactions a second.

Problem: that much electricity is very expensive, as is all of the specialized hardware required to do it. Those that do the work, miners, are commercial operations and expect to be rewarded for their effort. With Bitcoin and other currencies, this reward is the currency itself. The first miner that solves the problem is rewarded with a few Bitcoins, hence the unkind comparisons to Ponzi or MLM schemes. In any non-monetary application, these miners will need to be compensated to do the work running the blockchain. Given the inefficiency of Proof of Work, this will be orders of magnitude more expensive than a similarly sized centralized solution.

There are two solutions to this. Offer miners a token of some sort for their work, or run all the hardware yourself. The former is the basis of many ICOs, and most have more than a whiff of fraud about them. The latter is basically just a really crappy traditional system with some fancy terminology and a very expensive power bill.

Proof of Stake

There’s an alternative system to Proof of Work, which is Proof of Stake. In Proof of Stake the person holding the most old currency is selected as the person who will validate the latest block. Rather than each validator getting paid a set amount of new coins, they are paid a fee by everyone hoping to transact in order to validate the block. Rather than keeping the longest chain as the most valid, since the longest chain in Proof of Work is the most mined, the chain with the most old money in it is determined to be valid in Proof of Stake.

Proof of Stake solves some, but not all, of the most egregious problems with the current Proof of Work system. The power and silicon bill would be significantly lower, but not necessarily free. You’d still need to pay people to use their phone/computer/whatever to run transactions on it. The chain would also run more transactions, better than the miserable 4/s on bitcoin, but this would only increase the size of the overall chain. Remember, every transaction ever stays on the blockchain permanently. The Bitcoin blockchain is currently 157GB in size, and that’s at a very low transaction speed. The idea of everyone mining on their phone is just laughable.

Also, Proof of Stake doesn’t improve the real world interface or immutability problems above.

Scale

To be blunt, the performance of basically all blockchain systems today is garbage. The limited number of transactions that can fit into a block, and the amount of work it takes to prove a block means that blockchain systems using Proof of Work limits their maximum throughput to very low numbers. Bitcoin for example can handle on average 3-4 transactions a second, tops. Ethereum does better in the 15-20 a second range. Both pale in comparison to the average 1,667 transactions a second Visa handles per second based on their reported daily volume, with their peak volume probably being higher. To simplify, Visa can handle the transactions of an good sized nation state, bitcoin can handle the transactions of a few Costcos.

I question how many industrial systems are worth spending the electricity on and need a transaction volume in the single digits a second range. Probably not many.

Note: There are some plans to improve Bitcoin’s transaction speed, mostly by ditching the blockchain itself for all but the rarest of cases. Given that these solutions will appear any day now makes me doubt that they’re actually viable. These also include a lot of serious safety drawbacks that are not worth getting into here.

ICOs, Also Fraud

An interesting sub-genre of the cryptocurrency space are Initial Coin Offerings. This is where someone creates a new cryptographic coin representing a stake in some new venture. These coins are sold off to the highest bidder in order to raise funds, and then eventually the coins will be useful and valuable because magic. Needless to say, there is a ton of fraud in the ICO space.

First of all, ICOs are designed to look a lot like Initial Public Offerings (IPOs), except without all those pesky regulations. The fact that many ICOs confer no voting or dividend rights upon the purchaser, and sometimes aren’t allowed to be sold according to the contract has yet to dissuade the market. Even the most up and up ICO typically doesn’t provide any particular reason why these tokens should be worth anything in future.

Second, did I mention fraud? It’s estimated that up to 10% of the funds put into ICOs has been straight up stolen. Sometimes this is the creator of the ICO collecting bitcoin or whatever for the ICO and never delivering the token, simply replacing their website with a the word “penis” and laundering the currency. Other times its trivial integer underflow bugs letting someone steal $800k from a 4chan backed ICO. Half the time the funds are “stolen”, it is unclear whether or not a third party took it, or whether or not it’s an exit scam disguised as a hack.

Third, very few of these ICOs have even the slightest hint at being related to crypto or valuable in any meaningful way. I’ve covered the issue with supply chain blockchains above, but “dating on the blockchain” and “porn on the blockchain” is all meaningless bullshit, especially now that nobody really cares what you view in the privacy of your own home anymore. And that’s not even considering the insanity that is backing an ICO with bananas. No, I am not kidding. They claim that they they’ve raised $3,038,361.90, by the way.

For a good example of the nonsense of ICOs, look into the pre-mortem of Kodak’s ICO. The whole plan is bullshit from top to bottom, and includes a non-trivial amount of insider trading. If the Kodak board isn’t arrested within the next year for insider trading I will be genuinely shocked.

But What About Smart Contracts?

Ethereum is the one interesting outlier of all of the crypto currencies and blockchain technologies. Ethereum provides the user with a simple, if not problematic, programming language. You can generate programs, or “smart contracts” (let it not be said that crypto fans are bad at marketing), and run them on the Ethereum blockchain. You have to pay a small fee in ETH, called “gas” based on the complexity of your program, and the result of the program must be some sort of Ethereum transaction. Thus the value of ETH is nominally backed by the utility of running programs on the Ethereum blockchain itself.

On the face of it, smart contracts are an interesting idea. You could cut a lot of legal and human complexity/overhead out by making contracts that self execute. Most smart contract fans repeat the phrase “code is law” in reference to the above idea. Of course, writing programs that produce permanent financial consequences gives me some pretty serious anxiety, and I would hope that most senior engineers would feel the same. And given the number of high profile and high value hacks on Ethereum contracts over the years, it seems like my fears are well founded. That one of the hacks was serious enough to trigger a hard fork in Ethereum implies that I’m onto something. It turns out that “code is law” is a popular idea right up until enough people lose their money.

On top of that, as best I can tell a large percentage of Ethereum contracts are literal Ponzi schemes and ICO tokens, the later being easy to bootstrap on top of Ethereum using a protocol called ERC20. This calls into question the long term viability of “smart contracts”, given that the main usage for this system so far appears to be fraud and refreshingly honest fraud.

Conclusion

No, you probably don’t need a blockchain.

MDC and Thread Pools: A Bad Combination

Well written web services must have clear and easy to follow logs. Without good logs a programmer will be unable to diagnose or reproduce problems that might arise. And while many systems will keep logs in their reverse proxy like Nginx, a well written system will also have application/domain specific logs written within the application itself.

A common goal of application logs is to tie a given log line to a specific request. Because modern servers are multi-threaded, it is possible for multiple requests to be serviced at the same time, resulting in log messages from different requests being intermingled in the log output.

According to all the documentation I have found, the standard way to resolve this is to use the Mapped Diagnostic Context, or MDC. The MDC wraps a thread local hashmap, whose values can be used in your log patterns. On paper you could generate a UUID per request, insert it into the MDC and presto you have a UUID per request in each log line! Since threads are created per request, the MDC will be empty each time.

Except, that’s not really how Java programming works these days. Threads are expensive, and so for the sake of efficiency modern Java aims to minimize the number of threads created. This means using non-blocking IO (NIO), or reusing threads via Thread Pools where possible, which avoids creating new threads. As such there are quite a few number of APIs in Java 8 and some modern web servers that make it trivial to make your code non-blocking and use a common thread pool.

So, what happens to our MDC when we reuse threads? Well, we end up with the wrong MDC! Here’s some code for Java 8 that shows the problem:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.MDC;

import java.util.concurrent.CompletableFuture;

public class Main {

    public static final String CORRELATION_ID = "correlation-id";
    private static Logger logger;

    public static CompletableFuture<String> stepOne(String correlationId) {
        return CompletableFuture.supplyAsync(() -> {
            MDC.put(CORRELATION_ID, correlationId);
            logger.info("Step One");
            return "Foo";
        });
    }

    public static CompletableFuture<String> stepTwo(CompletableFuture<String> previous) {
        return previous.thenApplyAsync(x -> {
            logger.info("Step Two");
            return x + "Bar";
        });
    }

    public static CompletableFuture<String> stepThree(CompletableFuture<String> previous) {
        return previous.thenApplyAsync(x -> {
            logger.info("Step Three");
            return x + "Baz";
        });
    }

    public static String doAll(String correlationId) {
        return stepThree(stepTwo(stepOne(correlationId))).join();
    }

    public static void main(String[] args) throws InterruptedException {
        logger = LoggerFactory.getLogger(Main.class);
        doAll("correlation-id-one");
        doAll("correlation-id-two");
    }
}

This code is using the new CompletableFuture class from Java 8, which is roughly analogous to Javascript promises. What we do is set the correlation-id, then execute a sequence of asynchronous actions and log the output. If you run this code enough times, you will eventually get the output below:

1
2
3
4
5
6
12:13:55.465 [ForkJoinPool.commonPool-worker-1] INFO  correlation-id=correlation-id-one - Step One
12:13:55.466 [ForkJoinPool.commonPool-worker-1] INFO  correlation-id=correlation-id-one - Step Two
12:13:55.466 [ForkJoinPool.commonPool-worker-1] INFO  correlation-id=correlation-id-one - Step Three
12:13:55.467 [ForkJoinPool.commonPool-worker-1] INFO  correlation-id=correlation-id-two - Step One
12:13:55.467 [ForkJoinPool.commonPool-worker-1] INFO  correlation-id=correlation-id-two - Step Two
12:13:55.467 [ForkJoinPool.commonPool-worker-2] INFO  correlation-id=correlation-id-one - Step Three

Pay attention to the last line, which should have a correlation-id of correlation-id-two. Instead we have an earlier correlation-id because we happened to reuse a thread from earlier. This is an unmitigated disaster, as now you don’t have missing logs, you have misleading logs. In a less-simple scenario it would be absolutely impossible to tell whether or not that correlation-id was correct, and you might end up diagnosing bugs that don’t exist within your system because of this.

Java 8 and CompletableFuture make this much more plausible by making it very easy to use the ForkJoinPool. CompletableFuture provides a number of methods to create a new CompletableFuture, or to take one CompletableFuture and transform it into another. Most of these methods have at least two signatures: x and xAsync. The former will do all the work on the current thread, the latter will automatically use the ForkJoinPool to execute asynchronously. Optionally you can provide your own Executor, which might be backed by your own managed thread pool.

From a performance standpoint, this is amazing. I can separate the business logic from the execution strategies completely. With very minor code changes, sometimes only a method name, I can turn synchronous code to asynchronous or back again. But from a logging stand point this is very fragile. Correctly using the MDC depends on staying on the current thread, and Java 8 makes it very easy to hop threads by design. Worse, the above incorrectness is subtle, so your logs could be left incorrect for years without any immediate impact.

Recommendations

Don’t use the MDC, it’s too unsafe. Every time you change threads, you will either get an empty MDC (best case scenario), or MDC values from an older request (worst case scenario). At every single point where you might hop threads, it will be necessary to copy the current MDC settings to a local variable, close over it in your next lambda, and set the new thread’s MDC to the correct value before logging on the new thread. If any new asynchronous step is introduced without doing the above work, the correct values are lost for the rest of the request resulting in malformed or incorrect logs. Considering that adding “Async” to the end of a method name is enough to hop threads, this is a lot of work.

The easiest solution is to forgo logging request specific identifiers. Remove any reference to the MDC from your code and log configuration, and move on. If your request volume is relatively low, this might be a perfectly reasonable solution for you.

If you must track every single action down to a single request, you will need to pass around an object for each request which will contain any request specific information you want to log. You can setup logging interfaces that require the Request object to ensure log uniformity, which means that failing to pass this object will be a compilation error. As a side benefit, these custom logging interfaces would be extremely useful in enforcing consistent log messages, and a good place to inject statistics gathering.

Addendum

The MDC docs are incorrect, with sections of the documentation explicitly referencing out of date information. I draw your attention to the section titled “MDC and Managed Threads” which says the following:

A copy of the mapped diagnostic context can not always be inherited by worker threads from the initiating thread. This is the case when java.util.concurrent.Executors is used for thread management. For instance, newCachedThreadPool method creates a ThreadPoolExecutor and like other thread pooling code, it has intricate thread creation logic.

As it turns out, a copy of the mapped diagnostic context will never be inherited by a worker thread. This change guarantees that each thread gets a new, empty MDC. This documentation is correct for older version of logback, but it is not correct anymore. I’m sure the quote above was accidentally left in place, as the correct behavior is mentioned at the top of the document. It’s just a good reminder to read documentation carefully, and understand that humans can make mistakes in the docs too.

Java Without If

Over the past year my team has been doing something shocking to a lot of engineers: we’re favoring pure Java over Clojure. We aren’t rewriting all our Clojure code, but we definitely prefer Java for green field projects.

This post is not going to be a compare and contrast between the two, nor am I going to bash Clojure. Language compare and contrast posts always descend into flame wars, and it’s very easy to confuse the result of hard lessons learned with the benefits of a new language.

Instead I’d like to highlight a very strange aspect of our new Java development, and I hope that you’re sitting down for this. Except tests, I have fewer than a dozen if statements currently committed in our Java codebase.

It would be easy to assume that we’re just using Java’s method dispatch to replace if statements; rather than inspecting data and calling if/else on it, you can use interfaces and count on the implementation to provide the difference in behavior. But such an explanation is insufficient: objects don’t magically construct themselves from unstructured data, and Clojure is not without its own dynamic dispatch facilities.

Ultimately the real explanation for this strange code design lies in my colleague’s extremely exceptional Lambda library. It contains a lot of things that a Haskell/Scala developer would recognize such as Either types, function utilities, coproducts, etc. etc.

In particular I’d like to draw your eye to the Either type, which has replaced the vast majority of our explicit if calls. Either is the logical successor to the Java 8 Optional type. Optional represents the presence of a value of type T with Optional::of, or it’s absence with Optional::empty. Either on the other hand is parameterized to two values, L and R, and represents the presence of either a value of type L, or a value of type R.

Why is this a logical extension of Optional? Because while Optional is used to represent a result that may have no value (replacing a null), Either is used to represent a result that might have been a failure, replacing a thrown exception, with convention being that left side values represent failure and right side values representing success.

So, what does that buy us? Well, consider what Optional gets us in the following code snippets.

1
2
3
4
5
6
7
8
String x = Helper.functionOne();
if (x != null) {
  x = Helper.functionTwo(x);
  x = Helper.functionThree(x);
  if (x != null) {
    ...
  }
}
1
2
3
Optional<String> x = Helper.functionOne()
                           .map(Helper::functionTwo)
                           .flatMap(Helper::functionThree);

Optional gives us the ability to say “if a value exists, apply this function to it” repeatedly. It also gives us the ability to chain successive calls that return Optionals together with the flatMap function, eliminating the need for unsightly and error prone manual null checks. It’s also safe for map and flatMap to go from Optional<A> to Optional<B>, which might eliminate the need for intermediate variables in your code.

Either give us much of the same, but with the ability to represent why the computation failed with left values, along with the ability to chain together functions working on an Either type. All of the greatest hits of functional programming are provided for Either, including map, flatMap, and filter.

As a concrete example, imagine a hypothetical JSON parsing library. Parsing is tricky business, you’re all but guaranteed that a failure will happen at runtime. So how do you handle it? Previously you had 4 choices.

  • return null
  • return Optional<ParsedType>
  • checked exception
  • unchecked exception

Null is obviously bad, and unchecked exceptions are also risky. Checked exceptions guarantee that someone will deal with the issue, but they are extremely annoying, and might result in disparate and different exception handlers all over the place. Optional is nice, it’s safer than null and marks in the type signature that failure is an option, but it’s a bit lacking on explaining why a failure occurred.

What if instead this library returned Either<Exception, JsonNode>, or even Either<Set<String>, JsonNode>? The potential for failure is in the type signature again, we don’t need a try/catch, but if we want the unwrapped JsonNode we have to deal with the potential for a left value. And any functions we have that operate only on JsonNode can be passed in using the map function, making chaining a breeze.

Better still we can write other functions that might fail in this form, such as JSON validation, so that we can chain them together using flatMap. If the json parsing has failed, flatMap does nothing (it only works on right values), replacing the need for successive null checks, nested try/catch blocks, or complicated state checking during exception handling to return the correct value.

As a result of all this, you can easily imagine a JSON API endpoint looking something like this:

1
2
3
4
5
6
7
8
public HttpResponse handle(HttpRequest request) {
    return JsonParser.parse(request.getBody())
                     .flatMap(Validator::validate)
                     .map(ServiceObject::businessLogic)
                     .flatMap(JsonGenerator::generate)
                     .match(l -> HttpResponse.internalServerError(l.getMessage()),
                            r -> HttpResponse.ok(l));
}

All the potential failure cases are covered by returning an Either rather than throwing an exception. The very last step is match, which takes two functions to unify a potential left or right value to the exact same type, which in this case is HttpResponse.

What does this get me?

Well, first off I think it’s beautiful. I know that’s a subjective call, but the data flowing neatly from top to bottom without huge nesting if cases and early return values is very aesthetically pleasing to me.

More functionally it’s easier to refactor with the help of the compiler. If I want to add different return status codes to match different scenarios, the compiler helps me out a lot more than if I’m adding an extra return case. If I convert the left side to a HttpResponse early, the compiler will helpfully remind me that the later flatMap calls cannot change Either<HttpResponse, JsonNode> to Either<Exception, BusinessObject>. Such changes are easily fixed once the compiler has pointed it out, but extremely hard to find on your own.

But most fundamentally is that we’ve encoded our code’s states in the type system, not variable states. The potential for JSON parsing to fail is encoded in its type, not in the potential for a variable to null, or false, or for an exception to have been thrown. You’re leaning on the compiler to tell you if you’ve handled the failure cases properly, as the code won’t compile otherwise. Now instead of testing for runtime exceptions you only test to make sure that your business logic is correct.

If you’ve ever been interested in what the Haskell or Scala developers have been talking about with functional type safety, I’d highly recommend taking a look at Lambda to get a taste of it in Java.

My Increasing Frustration With Clojure

Edit: TL;DR: This is about how bugs in Clojure are handled by the Clojure Team, not just complaints about specific bugs I’ve seen.

First off, this is not a “I’m quiting in disgust” post. Those are childish and a waste of everyone’s time. But this is a post of frustration as I watch something I really like being slowly allowed to get worse.

First off, some history. My first job out of College was in Common Lisp, and I love/hated it. The power it brought and the pain it brought were both one and the same. No modern libraries, no modern build tools (this was before QuickLisp). One on hand, I loved working with paredit and Emacs, being able to quickly fly about my code and manipulate it in blocks rather than line by line. On the other, I couldn’t help but be envious of those who could actually ask for help from a functioning open source community.

A few years of Python, Ruby, and Javascript later, I found Clojure. And I thought I’d found the solution to literally all of the things. Paredit works again? Check. A thriving open source community? You got it. Deploy as a Jar rather than CL’s hilarious “dump the state of a running program and call it good” setup? Fuck. Yes.

And beyond the superficial things, there was a lot to love, especially coming from a more recent brush with Ruby on Rails. Clojure makes it very easy to make things referentially transparent, and it tends to favor explicit calling semantics over convention (or more derisively, “magic”). This means that a Clojure code base will require more plumbing code, but that also means it’s possible to navigate to the code that does routing and understand how it works, no more having to search through your framework’s codebase just because they do dynamic method creation and method_missing magic.

As far as I was concerned, the editor was the only weak point for Clojure. Back when I got into Clojure Cursive was still brand new, Emacs really was the only editor that was worth using and even it had some stability and usability issues. But I assumed that continued interest would stabilize Emacs, bring Vim up to speed, and improve Cursive to the point where it would be competitive with Emacs/Vim.

But all was not well, and if I’d paid attention I might have noticed a few places where the core Clojure’s teams priorities didn’t seem to make much sense to me. And now that I work in Clojure professionally, I really cannot ignore them or remain silent about them any more.

The core Clojure team prefers green field development over improvements and bug fixes to existing code to a degree that deeply worries me. I no longer trust that any issues I find stand a chance of getting fixed, as all the bugs we’ve posted are either in limbo, or flat out rejected. Multiple members of my team have given up on posting new bugs because they have no faith that it’ll help anyone.

These are pretty heavy and vague accusations, so I’m gonna break this down a bit to make it clearer and easier to digest.

Ignorance or Apathy of Underlying Principles

Programming isn’t math per-se, especially in a language that’s not explicitly based on Category or Type theory. That said a lot of the things that we do are backed or defined by mathematics, and to ignore that is to guarantee bugs. This is most clear in clojure.set which contains functions that are supposed to mirror the definitions created by Set Theory like union, difference, intersection, etc.

And the namespace is completely riddled with bugs. union returns duplicates if some of the inputs are lists instead of sets depending on their length. intersection will either return nonsense values or throw a ClassCastException if you provide it anything other than sets, again dependent on data.

On their own, this is no big deal. Bugs happen, there’s really no point in berating people just because they made a mistake. Instead the bug gets fixed as best and as soon as reality allows and we all move on. In fact, for the above bugs there are two possible fixes: raise an IllegalArgumentException if anything other than sets are provided, or coerce lists and vectors to sets before continuing. Both of these approaches are valid due to the fact that this is a dynamic language that defaults to immutable collection semantics; which one you pick is then a matter of how you want to affect your downstream users.

Oh wait, some of these bugs were filed in 2009, 7 fucking years ago! Here comes the berating. These functions are tiny, a simple implementation of union is one line. And while they’re heavily used, they’re simple in usage and signature; no need to change a lot of call sites to fix this bug. There are only two reasons to explain why these bugs have not been fix; they either do not understand that this is an issue, or they do not care.

Actually, their comments on the issues lets us know that they do not understand that this is an issue. Rich Hickey said in 2009 “the fact that these functions happen to work when the second argument is not a set is an implementation artifact and not a promise of the interface”. How you define getting the wrong type with nonsense values counts as “working” is beyond me. Is it just because it doesn’t throw an Exception? Anyone here prefer bad data instead of exceptions when dealing with functions like this? I doubt it.

Inconsistency Between Best Practices and Clojure Implementation

Clojure includes a pretty powerful concept called protocols. Basically a protocol is an interface that can be added to classes after the fact, and lets you dispatch to different behavior silently at run time.

This is pretty neat, it lets you abstract over multiple data types and include Java classes in the fun. For example ISeq provides all the methods needed to iterate over a collection and it works with all the Clojure and Java data types. So you can use Clojure’s map function over its own data types and Java’s because it depends on the seq interface.

As you can imagine, this is the recommended way to work with things. Rather than having to do cond or if logic on various classes, define and use an appropriate protocol and you’re good to go!

It sounds like a good theory doesn’t it? But Clojure itself doesn’t actually do this. Clojure.core contains 89 calls to instance? in order to check runtime type, instead of the helper methods to check for protocol implementation.

Here is a bug found by my colleague that highlights this issue. List and Vector are both seqs, but into for a map only accepts vectors, lists causes a ClassCastException. This is kind of nuts because an IllegalArgumentException makes more sense, and there’s no practical reason to differentiate between a list of two elements and a vector of two elements. Actually, Clojure considers [1 2] and (list 1 2) to be equal, so this really makes no sense

Even more obnoxious, it was closed as wontfix. Apparently a single sentence in the docs is good enough for the Clojure team, as well as a paper-thin argument about performance on a 2 element list. So not only is this just broken in a barely documented and very surprising way, Clojure itself ends up programmed in a way that isn’t recommended by the Clojure docs.

This has spread to other projects. Om has a bug where lists aren’t acceptable in its data structures, only maps sets and vectors. To say that I was treated pretty shabbily by David Nolen on this issue almost goes without saying. Naturally the intro docs barely call this out, and the docs dedicated to the troubled component does not mention this at all. To be fair, the troubleshooting guide explains this, but in my opinion that’s probably a clue that the bug is common enough that you should find a fix for it.

Show Stopping Bugs Remain Untouched

There are a shocking number of big, bad bugs hiding in the Clojure Jira, some really old

I could go on, but I feel that I’ve made my point. Bugs, even major ones are either closed as “wontfix”, or are ignored for years despite the pain felt by users. That’s not even covering the dismissive and distrustful attitude given in some of the replies.

Strange Priorities

The Clojure team appears to be super focused on new features, at the exclusion of existing namespaces. The big highlights from the past year or so have been Transit, Transducers, and Spec.

These are okay, I guess. We use transit a bit, and it’s kinda cool. But we really don’t use 90% of its features, it’s basically JSON for us that can convert numbers to BigDecimals.

We have yet to find a place that Transducers would help us. They’re neat enough, but the built in lazy sequences are working A-OK for us, so we don’t really feel the need to change over.

I’m not holding my breath for Spec. It doesn’t fix anything for me that other libraries aren’t already providing.

Know what hasn’t seen any major improvements in forever? Clojure.test. Clojure.Test is frankly sad. Fixtures are done via some global state, and you can’t even setup fixtures to work across the entire test suite. Need a database to run functional tests? Well either you need to override the main test runner (good luck running individual tests now!) or you have to setup each namespace to open and close its own database connection (don’t forget, or your DBA will wonder why Emacs has 1000+ database connections). I’m 100% behind the idea that I’ll have to write a bit of glue code, but without anywhere to put that code I’m kind of screwed.

And then there is the is function. It’s literally the only assertion provided by clojure.test. It’s this fancy little macro that grabs its body, evaluates it, then uses the body to produce a human readable message about the failure.

And it’s garbage. The fact that plugins exist to make this easier on the eyes should tell you everything you need to know. Oh but don’t use that with Emacs/Cider! It’ll crash the Cider plugin, which is trying to parse the default output.

Back when I used Emacs, I had a stash on my box that disabled AOT, pedantic checking, and the humane-test-output plugin from my project.clj in order to use Cider. Without that stash applied Cider wouldn’t start, couldn’t reload code, and would crash when running tests. Now that I use Cursive that’s less of an issue, but it’s still kind of nuts I had to decide between a working editor and readable output when I ran lein test

Sorry, I didn’t even highlight the craziest bit of that last paragraph, did you catch it? I had to disable humane-test-output from my project.clj. That’s because you install it by injecting some code in project.clj that redefines some multi-methods, because there’s no plugin architecture. How nuts is that?

Now I might hear you say “You don’t have to use clojure.test!”, and you’re right. But clojure.test has clearly won in the Clojure testing namespace. The only real competitors for clojure.test are Speclj and Midje. I’ve literally never met someone in person that’s used Speclj, and Midje is super polarizing because it’s basically a collection of magic macros. The fact that the second entry for Midje is about CircleCI rewriting from Midje to clojure.test should tell you a lot.

So why don’t we have more creature comforts for clojure.test? I’m not really sure. As far as I can tell the change to it was the inclusion of test.check, but that really was nothing more than simple-check getting renamed and transferred to Clojure ownership.

Okay, Now What?

As I stated before, this isn’t a “I’m quitting Clojure!” post. Partly this is because I work in Clojure on a daily basis, and I both like my job and am professional enough to keep working despite my complaints. And partly this is because I do not have a replacement for Clojure in mind for my own personal projects. But off the top of my head, there are the things I’d like to see fixed in the Clojure areas.

  • More love for clojure.test.
  • No tolerance for bugs that result in bad-data. Built in functions should either work, or throw an understandable exception.
  • Friendlier responses in Jira. Someone who has gone to the work to sign up and try to help out should be treated with more respect.
  • Fix underlying compiler bugs before adding features. The other way only codifies bad behavior and guarantees that it cannot be fixed.
  • Understand that if enough people have the same issue, it’s the codes fault and a FAQ entry is not good enough.

Basically I want Clojure to be a simple to use language backed by a friendly and active community. What I see now is drifting in the wrong direction, and I’d like to see that corrected.

Integrating Test.Check and Javascript

Introduction

I was recently on The Cognicast with Craig Andera where we discussed using Generative Testing on a large non-Clojure(script) codebase, in particular Ruby on Rails and Backbonejs. If you haven’t listened to the show yet I highly recommend it first.

As I promised on the show, I’d like to share how we used Test.Check to test our Backbone.js code base. Our overall strategy for testing Javascript is going to be:

  1. Compile JS into one file (just like prod).
  2. Compile tests into a single file.
  3. Combine them in a PhantomJS process.
  4. Let the tests do their thing.

While we have been super pleased with the results of Generative Testing, there have been some hurdles for getting it to work for us. In this post I’m going to go over how to setup Test.Check to work with your Javascript app, and how to dodge all the pitfalls I found.

Here are the challenges that lie between us and Generative Testing bliss.

  1. Picking the right library
  2. Setting up Leiningen & Cljsbuild
  3. Dodge PhantomJS issues
  4. Avoid mangling your app, and defeating dueling dependencies

Picking the Right Library

First of all, there are two libraries that exist, Test.Check and DoubleCheck. Because Test.Check is an official Clojure library it is Clojure (JVM) only, so I recommend DoubleCheck (maintained by Chas Emerick) which is capable of cross compiling to Clojure and Clojurescript.

The only catch with DoubleCheck is that it’s not currently possible to segregate tests via metadata for running in groups. But with the way we will be running these tests that won’t be an issue.

Setting up Leiningen

First step, install Leiningen and create a project.clj wherever you Javascript code is. We’re going to use Cljsbuild to compile our testing code for execution. I in put my test code in test/cljs (because I have clj and cljs based tests), and send the compiled output to tmp/tracker-cljs.js. Note: this guide only works for Clojurescript 0.0-2234, I need to figure out why the latest build of Clojurescript doesn’t work.

I highly recommend you send the output of the compilation process to either a temporary or gitignored location. The output will be fairly large, and it will bog down your repository with its size.

I don’t want to duplicate the Cljsbuild how-to, so if you don’t know how to make it work, you should check their docs. Our project.clj is reproduced at the bottom of this post if you have issues.

At this point, we can write the simplest test possible:

1
2
3
4
5
6
7
8
9
10
11
12
13
(ns tracker-cljs.simple-test
  (:require [clojure.test.check :as core]
            [clojure.test.check.generators :as gen]
            [clojure.test.check.properties :as prop]
            [cemerick.cljs.test :as t])
  (:require-macros [clojure.test.check.clojure-test :refer (defspec)]
                   [clojure.test.check.properties :refer (for-all)]
                   [cemerick.cljs.test :refer (is)]))

(defspec simple-test 10
  (for-all [v (gen/such-that gen/not-empty (gen/vector gen/int))]
    (println v)
    true))

PhantomJS issues.

In order to run the tests, you would typically have a :tests section in :cljsbuild that looks like this:

1
2
3
:test-commands {"unit-tests" ["phantomjs" :runner
                                          "compiled-application.js"
                                          "tmp/compiled-tests.js"]}

This will load our JS into the app, along with the tests, and then run them. But you might notice errors that look like this:

1
SECURITY_ERR: DOM Exception 18: An attempt was made to break through the security policy of the user agent.

That means that your app code is trying to access local storage, and PhantomJS does not like it when you do that without loading a webpage. The solution for this is to start a server so we have a page to visit, and visit it via PhantomJS. So on Tracker we use the following two bits of code.

generative_runner.js, to visit the actual page:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
// reusable PhantomJS script for running clojurescript.test tests
// see http://github.com/cemerick/clojurescript.test for more info

var page = require('webpage').create();
page.onResourceError = function(resourceError) {
    page.reason = resourceError.errorString;
    page.reason_url = resourceError.url;
};
var fs = require('fs');
var sys = require('system');
var success;

page.onConsoleMessage = function (x) {
    var line = x.toString();
    if (line !== "[NEWLINE]") {
        sys.stdout.writeLine(line.replace(/\[NEWLINE\]/g, "\n"));
    }
};

page.open('http://localhost:4500', function(status) {
    if (status !== "success") {
        console.log("Couldn't load page");
        phantom.exit(1);
    }
    for (var i = 1; i < sys.args.length; i++) {
        if (fs.exists(sys.args[i])) {
            if (!page.injectJs(sys.args[i])) throw new Error("Failed to inject " + sys.args[i]);
        } else {
            page.evaluateJavaScript("(function () { " + sys.args[i] + ";" + " })");
        }
    }

    page.evaluate(function () {
        cemerick.cljs.test.set_print_fn_BANG_(function(x) {
            console.log(x.replace(/\n/g, "[NEWLINE]")); // since console.log *itself* adds a newline
        });
    });

    success = page.evaluate(function () {
        var results = cemerick.cljs.test.run_all_tests();
        console.log(results);
        return cemerick.cljs.test.successful_QMARK_(results);
    });
    phantom.exit(success ? 0 : 1);
});

And a rake task to stand up a server and run everything. If you don’t use Rails for your Javascript code you might need to use different commands to compile, but the intention remains. The WEBrick server provides a blank page for us to visit and run our tests on, which prevents PhantomJS from raising security errors.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
require 'fileutils'
require 'webrick'

namespace :test do
  desc "Run ClojureScript generative tests"
  task :generative do
    server = WEBrick::HTTPServer.new({:Port => 4500, :DocumentRoot => ".", :BindAddress => "0.0.0.0"})
    Thread.new do
      server.start
    end
    exitCode = 0

    begin
      Rake::Task['assets:clean'].invoke
      Rake::Task['assets:precompile'].invoke
      exitCode = system "lein cljsbuild test"
    ensure
      server.shutdown
    end
    exit exitCode
  end
end

To make all this work together, update project.clj to reference the generative_runner.js file instead of :runner, and use rake test:generative to kick off the run.

Don’t Mangle Your Code

If your application is anything like Tracker, you might use some Google Closure dependencies without using the entire Closure compiler. And even if you don’t need use Closure, you certainly have functions and classes in the global namespace that you don’t want mangled.

To get around this, I recommend the following settings:

Add :libs [ "compiled-application.js" ""] to the cljsbuild section in project.clj. This prevents DoubleCheck compiler errors due to classpath issues, and it allows the Closure compiler to see everything that your application provides. So if your tests and applications have overlapping Closure dependencies you won’t get double provide errors.

Secondly I recommend that you only use the simple compilation mode. This will prevent Closure from mangling global names, which will make debugging easier and prevent your tests from being able to find the production code. The space saving and code elimination that advanced mode provides is more of a problem than a benefit for testing, so it’s not worth fighting to get advanced to work.

You can fiddle with source maps if you wish, but I haven’t had much luck or use for them; simple compiled Clojurescript is easy to read, and most of the serious errors have come from the 43k application javascript file, not the test file.

Have Fun and Make More Tests

Once you have that going, it should be possible to open up and create increasingly complicated tests. As a teaser and a good example, the following code caught a tricky JS ordering bug.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
(ns tracker-cljs.panel-items-test
  (:require [clojure.test.check :as core]
            [clojure.test.check.generators :as gen]
            [clojure.test.check.properties :as prop]
            [cemerick.cljs.test :as t])
  (:require-macros [clojure.test.check.clojure-test :refer (defspec)]
                   [clojure.test.check.properties :refer (for-all)]
                   [cemerick.cljs.test :refer (is)]))

(defn ids [items]
  (if (seq? items)
    (map (fn [item] (.get item :id))
         items)
    (map (fn [item] (.get item :id))
         (.-models items))))

(defn create-models [ids]
  (map (fn [x] (Backbone.Model. (js-obj :id x)))
       ids))


(defspec sort-check 100
  (for-all [v (gen/such-that gen/not-empty (gen/vector gen/int))]
           (let [models (create-models v)
                 sorted (sort v)
                 subject (tracker.PanelItems.)]
             (.reset subject (apply array models))
             (.refresh subject (apply array (sort-by #(.get % :id) models)))
             (is (= sorted
                    (ids subject))))))

And the following is our project.clj, with unnecessary details elided for readability.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
(defproject generative-testing "0.0.1-SNAPSHOT"
  :plugins [[lein-cljsbuild "1.0.3"]
            [com.cemerick/clojurescript.test "0.2.2"]]
  :dependencies [[org.clojure/clojurescript "0.0-2234"]
                 [com.cemerick/clojurescript.test "0.3.1"]
                 [com.cemerick/double-check "0.5.8-SNAPSHOT"]
                 [org.clojure/clojure "1.5.1"]]
  :cljsbuild {:builds [{:source-paths ["test/cljs"]
                        :compiler {:output-to "tmp/tracker-cljs.js"
                                   :libs [ "public/web/assets/application.js" ""]
                                   :optimizations :simple
                                   :pretty-print true}}]
              :test-commands {"unit-tests" ["phantomjs" "lib/generative_runner.js"
                                            "public/next/assets/next/next.js"
                                            "tmp/tracker-cljs.js"]}})

Also, the following function is helpful for converting from Cljs data structures to pure Javascript ones. It causes some compiler warnings, but they appear to be harmless.

1
2
3
4
5
6
7
8
9
10
11
(defn clj->js
  "Recursively transforms ClojureScript maps into Javascript objects,
   other ClojureScript colls into JavaScript arrays, and ClojureScript
   keywords into JavaScript strings."
  [x]
  (cond
    (string? x) x
    (keyword? x) (name x)
    (map? x) (apply js-obj (flatten (map (fn [[key val]] [(clj->js key) (clj->js val)]) x)))
    (coll? x) (apply array (map clj->js x))
    :else x))

Good luck, and don’t hesitate to reach out to me on Twitter if you have any questions!

Unusual Productivity Hacks

The internet is lousy with productivity ideas, mostly about how to work harder or longer. I personally believe that good productivity is about maximizing per hour results, not working harder. And the fastest way to improve your productivity is to eliminate some of the things slowing you down. So rather than going over the usual suspects, let’s take a look at eliminating some of the low hanging fruit.

1. Conquer Your Diet.

What you eat is the cornerstone of who you are and what you do. The proteins in your muscle, the fats in your cell walls and your brain, and the amino acids used throughout your body must all come from, or be synthesized from your food. Low quality food products like trans fats have been connected with apathy, depression, and might be related to ADD. In order for your brain and body to perform at peak levels you need to give it high quality food to repair and refuel.

2. Sleep

Sleep is massively underrated. Everyone knows at this point that Americans are typically not getting enough sleep on a nightly basis, but distressingly few people consider it to be an issue. After all, hours spent asleep aren’t hours spent working right? Unfortunately it isn’t that simple. Insufficient or low quality sleep is one of the fastest ways that we know of to destroy per hour productivity. Get sleep or waste your precious waking hours in a mind fog.

3. Know when to stop.

Athletes regularly destroy their bodies by “over training”; exercising to the point of injury or chronic fatigue. The results of over training are often slow growth or even frustrating setbacks despite hundreds of hours at the gym or on the track.

Mental workers regularly do the exact same thing to their mind by working well past the point of mental burnout. There is very little use in working when you are not going to be putting out at least average results, and you risk ruining your morale after hours of low-results work. Instead of ritualistically working even when you are spent gain an intuitive sense for when you will accomplish little and instead go recharge and try again later.

4. You must come out unharmed 1 time or 1000 times.

No productivity regime is worthwhile if you can only maintain it for 2 weeks at the start of each year. To be successful, you must find a pattern that you can maintain years. Whether that is a small amount per day or a cycle between intense work and relaxation, you must find a balance between work and play or you will be plagued by failures to meet your goals.

5. Know thyself.

Everyone wants to be successful, but most people overestimate how much money motivates them. Find ways to motivate yourself with something other than riches, or better yet find something that you love to do. Love of the work will make it easier to get up, or home, every day and work rather than abstract future financial rewards.

The Swordsman and the Software Engineer

One of the largest mistakes you can make as a knowledge worker is to focus 100% of your time on your craft. It’s easy to believe that specializing and focusing will make you better than your peers, but I do not think that is the case. Not only will specializing cause you to plateau earlier than your peers, it will cause you to be less happy and healthy than your diversified peers.

A bit of background at this point would probably be helpful. I’m a software engineer and I’ve coded both professionally and on a hobbyist basis for nearly a decade. After a particularly stressful few months at a previous job, my fiancĂ© forced me to join a local gym to de-stress. The gym focused on various European martial arts and I ended up in a class for the Italian longsword circa 1409.

A few years ago I would have suspected that choosing to surrender 2-8 hours a week to swinging steel around instead of programming on hobbyist projects would slow down my growth. Now I believe that I owe a lot of my growth, professionally and as a human being to this practice. A lot of what I’m going to cover here will probably be old news to anyone who was heavily involved in sports, nor is it particularly unique to fencing. That being said I’m fairly confident that a lot of knowledge workers have lost the involvement with physical activities they might have had, or never were all that “athletic” even in school.

The biggest modern challenge is that humans are not wired for the type of work that we now do. We are a fairly clever species by nature, which is why we have been making art for hundreds of thousands of years. But we are still more or less genetically and mentally hunter gatherers from 100,000+ years ago who largely worked for their survival. Our bodies, genes, and minds are wired to expect a specific ratio of play and physical activity to signal that all is well. Unfortunately we work a lot longer than our ancestors did, and under very different conditions.

This high level of nothing but work, physical or mental, indicates to our bodies that times are tough and that it should release stress hormones to help us survive the coming hard times; these stress hormones tend to have serious detrimental effects on mental performance and long term health. The phrase “all work and no play” may be over-used, but it does have some truth. All work and no play leaves Jack pumped full of cortisol, short on sleep, and low on testosterone.

Secondly, most knowledge workers spend their entire time thinking only with their frontal cortex, or the analytical portion of the brain. This is very helpful if your job involves concentrating on difficult problems all day, but it is incredibly easy to let that portion of your brain become the only driving factor on your day to day life. The brain, like your muscles, should have ample opportunity to exercise all of its faculties and have recovery time between each heavy usage. Expecting it to be able to focus deeply on your work day in and day out without giving it time to relax is simply asking for lowered performance and burnout, and only working on one aspect of your mental performance is akin to only doing curls at the gym; the result is an odd shape with very little practical strength.

Thankfully exercise and hobbies help other parts of the brain. This is one of the things I love about fencing: it isn’t very analytical once you actually start using it. There are a ton of cuts and guards to be memorized, but you never have time to think about it when you are actually fencing. All of the drills are designed so that your mind and body learn to move with instinctual grace from one guard to another. There is very little conscious thought that happens mid-move in a match; there simply is not enough time to stop and think. Instead you learn to have an internalized notion of time and measure, and an ability to make new decisions as the fight progresses quickly and correctly.

And while none of this directly relates to software engineering, it has a positive effect on my daily work. The ability to move with a fight and think with my toes and fingertips have given me a greater appreciation to the importance of gut instinct in more situations. And the constant practice of excluding my analytical mind in a fast moving match have improved my ability to enter a flow state more easily. Combine these things with the general good effects of mental down time and exercise, and I think it’s hard to argue that my time would have been better spent working on hobbyist projects.

Confessions of a Language Snob

I am a language snob. In particular I fall head over heels for most functional languages, especially MLs and Lisps. Show me the latest and greatest Javascript framework and I will just wish I had immutable data types and a saner method dispatch system. I try to keep quiet about it at work with varying degrees of success, but it’s frustrating to work around one language’s problems when you know of other solutions.

The difficult reality that few admit is that every language has a weak point. Ruby is slow and the lack of import semantics and proper namespaces makes it difficult to determine what code will run. Python lacks a good lambda and whitespace sensitivity brings new difficulties. Javascript is just pure insanity. Lisp is poorly standardized and tends to have subpar documentation. The list goes on and on. No language is perfect, but it’s very easy to focus on the high points of one language while working through the low points of another.

The real bummer about being a language snob is that there’s really nothing to be done about it. For any given issue there will always be another language that exceeds in that area, but it’s almost always insane and impractical to convert your entire company over to it. So even if you think Go would solve every problem that your Python codebase has, and you know that the downsides wouldn’t be insurmountable, the simple reality is that convincing the organization to throw away their perfectly good Python code on a whim is insane at best. And that’s assuming that converting to your language wouldn’t come with downsides worse than the language you are coming from.

Thankfully, there is an upside to being a language snob. Polyglots have a far more flexible understanding of what a program should do, especially when they’re used to a wide range of paradigms. Someone who has done nothing but C or Java programming might have very little context into why mutable state can be so problematic, but someone who knows Clojure or Haskell will know the tradeoffs of mutable vs. immutable state intimately. Each new paradigm a programmer embraces means that they have more internal views on how a particular problem could be solved, a bit like having an experienced team in your head to discuss the merits of various techniques at lightning speed.

While it may be very frustrating to know of better solutions in other languages, there is a benefit to knowing about them. Being a language snob can help you evaluate your choices more effectively and discover solutions and strategies that might not be immediately obvious if you only knew one language. And between being a bit of a snob and attempting to shoe-horn every problem into a one-size fits all paradigm, I’ll take being a snob.

The Primacy of the Build Tool

No programming language stands alone. Besides the compiler, every programming language includes an ecosystem of libraries, build tools, analyzers, debuggers, and other utilities. Languages often rise and fall depending on the quality of these tools and libraries.

For every language there needs to be one central item upon which every other tool depends. In most languages, this is the compiler or interpreter. Your Rails project is entirely dependent on the version of Ruby provided by the current environment, and similarly Maven depends on the version of javac and java available on the path.

Unfortunately, this makes our code more fragile and dependent on the machine it was first created on. Someone cloning your code from a different machine must take care to ensure that their development environment is close to the original authors, and deployment must ship the correct compilers and interpeters for production to work well. We have created tools to help enforce the requirements of the code, but they are fragile and make upgrading dependencies a pain, as anyone who has had to fight with RVM can attest.

The one exception to this I have found is Clojure. Clojure inverts the normal order making the build tool the central item, with the compiler provided by the project definition file.

1
2
3
4
5
6
7
8
(defproject foo "0.1.0-SNAPSHOT"
  :description "FIXME: write description"
  :url "http://example.com/FIXME"
  :license {:name "All Rights Reserved."}
  :dependencies [[org.clojure/clojure "1.5.1"]
                 [org.clojure/clojure-contrib "1.2.0"]
                 [clj-time "0.6.0"]]
  :profiles {:dev {:dependencies [[midje "1.5.1"]]}})

The beauty of this change is that it makes setup trivial for another developer. All they need is the same build tool, and it will deal with the correct versions of both the compiler and any libraries for the project. Have other projects that depend on different versions of the compiler? The build tool only cares about the dependencies in front of it, and will call the correct version from the correct project.

This also makes upgrading trivial. Want to try Clojure 1.6.0? Change “1.5.1” to “1.6.0” in the above snippet. Want to write a library that supports multiple versions of the compiler? The build tool supports profiles which allow you to swap out compilers trivially because it’s just a dependency.

1
2
:profiles {:1.3 {:dependencies [[org.clojure/clojure "1.3.0"]]}
           :1.4 {:dependencies [[org.clojure/clojure "1.4.0-beta1"]]}}

Deployment gets easier as well. If you’re deploying an uberjar, the core libraries you tested against are also shipped to production in the same jar. No need to upgrade your deployment scripts when a new version of Clojure comes out, as everything is included automatically.

There is one catch to this wonderfulness, which is that Clojure depends on the JVM, and the build tool cannot change the JVM around. But Clojure has very simple requirements, Java 1.6 or greater, which makes it simple to deploy anywhere.