In this post, I will be sharing a horrible, no good hack for the Emacs Cider Clojure REPL that you should definitely never use yourself.
When debugging or executing a Clojure/Clojurescript program, I often want to execute functions in my program from the Clojure REPL. However, as much as I love the Clojure syntax for programming, it's pretty inconvenient for regularly executing commands in a program you've written.
For instance, I have a task tracking app written in Clojure. Every time I wanted to add a new todo item through the REPL, I used to have to type something like this:
> (a "iron curtains") Item added. NIL > _
Though I was able to streamline the command by having the single-letter function name, this command remains incredibly awkward! What I really would prefer to type is this:
> a iron curtains Syntax error compiling at (*cider-repl*:0:0). Unable to resolve symbol: iron in this context Syntax error compiling at (*cider-repl*:0:0). Unable to resolve symbol: curtains in this context
Of course, since this shorter command does not obey the parsing rules of the Clojure reader, it just leads to syntax error in the REPL. This raises the question: Is there any way we can work around this limitation and enter custom commands into the Clojure REPL, using our own rules for parsing the command? The answer is... yes, sort of.
At this point, some of you may remember my classic Lisp tutorial, named Casting SPELs. In this tutorial, I implemented a text adventure game in a Common Lisp REPL, letting you enter commands such as "GET BOTTLE" and "WALK EAST". Naturally, the tutorial had to make compromises to work around REPL limitations, for the exact same reasons I'm outlining in this post... so as you can see, I've already had a decade-long love-hate relationship with inflexible Lisp REPL syntax.
Let's try to find a work-around to this issue once and for all!
Certainly the Clojure REPL will never, ever accept "
a iron curtains" as valid syntax in the reader, unless we're prepared to write our own custom fork of the Clojure programming language. But if we're using Emacs to run our REPL, we can do a little somethin' on the Emacs end of things, to wrap our command in a way that the Clojure reader will accept:
(defun wrap-clojure-command () "takes a command written at the cider prompt and executes it as (repl-command \"...\")" (interactive) (move-beginning-of-line nil) (insert "(repl-command \"") (move-end-of-line nil) (insert "\")") (cider-repl-return)) (global-set-key "\M-z" 'wrap-clojure-command)
With this command, we can now enter custom commands into the Cider REPL, then hit the
\M-z hotkey instead of
ENTER to execute these commands. Then, the Emacs function wraps our REPL command within a standard Clojure string, inside a function call:
> a iron curtains | Pressing \M+z | V > (repl-command "a iron curtains")
To take advantage of this Emacs hotkey, all my Clojure/Clojurescript programs then have a function named
repl-command that is then responsible for parsing my REPL string and performing the appropriate action.
By default, Cider launches new REPL sessions in the
user namespace. I like this default behavior, since it forces me to explicitly declare any namespaces I'm interacting with as I work in the repl. However, if I'm executing one of my custom repl commands, I don't want to have to deal with namespacing issues. Therefore, I have the following function declared in my personal Clojure libraries:
(defn user-repl-command [repl-command] (binding [*ns* (create-ns 'user)] (eval `(def user/repl-command ~command))))
This command takes an arbitrary function and declares it in the
user namespace as
user/repl-command. So at the bottom of the "core" module for each of my Clojure apps I can now declare my custom REPL command handler, to "register" it for use in the REPL:
Now I can immediately execute arbitrary commands for my Clojure app right in the Clojure REPL, using my own custom command syntax, even in the default cider REPL namespace!
Certainly, this is all very hacky, but I've used this workflow all day, every day, for about a year. This, alone, seems like a good enough reason for sharing my REPL workflow with others.
But certainly I'd love to come up with a less hackish solution to this problem. If any of you have ideas for cleaning up my worflow, please share them on twitter!
Since I just got into 3D printing, it was inevitable that I would create an official Lisp Alien 3D model. I've finally been able to print it out, and today my 8 year old daughter helped me pose it in some killer action shots!
It comes in two STL file versions, depending on whether you want to make a single material or dual material print. Grab the files here:
I modeled the Alien in Shapr3d on an iPad Pro. For a modeling program that is used primarily for industrial modeling, I was pleasantly surprised how well I could create the organic shape for the Lisp alien body. The reason I've decided to learn how to use a more "industrial" program is that I've had trouble in the past with 3D modeling in that these sorts of programs can get glitchy when you start creating more complex designs. Shapr3d did not disappoint me, it could handle very messy boolean operations and beveling without even a single hard crash.
I printed the physical copy you see in these photos on my Elegoo Mars Resin printer, using Elegoo Clear Green for the body & Elegoo Standard White for the add-ons. It came out almost perfect, though I definitely had to sand it a bit to get the smooth alien skin as a finish.
Here you can see some more shots of the alien going about its day:
I gave the alien a hard time for drinking while riding his ATV, but he swears it's fine because he was driving on private property (I have my doubts though that that's correct...)
Anyway, I consider these models to be public domain, feel free to use them for any physical or digital projects that you like! If any of you 3d print additional versions of the alien, be sure to send me a tweet!
I like to think of myself as a creator: I love to program, write, create art, and build stuff!
And, like most other creators, I love reading about crazy productivity schemes that promise to help curb procrastination... oh, to finally attain the dream of ultimate productivity!
But at the end of the day, there's only one such system that ever helped me in any appreciable way: The classic "Getting Things Done" system. (Read the box below for a summary of the minimal variant of GTD I've used for many years, if you are not yet familiar with this system)
However, despite its benefits, it always felt to me like GTD just doesn't work well for Creators. In this post, I'm going to describe a new productivity system I've created, called Task Tension, that makes the GTD system more compatible with the creator mindset.
To understand the rest of this post, you'll need to have a basic understanding of the GTD system. Those of you who already know GTD can skip this box, which describes the simplified variant of GTD that I use.
In my minimal version of GTD, all you need to do is maintain four lists:
For a quick example, a typical task for me might be "Cancel Hulu". An example project might be "Get Oil Change" which would have a concrete task associated with it of "Call Auto Shop for appointment" (Note that all projects in GTD should always have at least one "task" or "waiting" entry associated with them, otherwise the project would be permanently stuck.) Finally, in my "someday" list I have items such as "take online Linear Algebra class", which is not an active project right now, but something I want to keep in mind as a potential project in the future.
There are several other features that are part of classic GTD that I personally do not use and are not relevant to the remaining discussion in this post (Such as the "Inbox", "Contexts", "References" or "Triggers")
Creators are people who creates things for others, whether through writing, art, software, music, or another medium. There are many traits and strengths that are shared amongst great creators. However, almost all of them are good at handling feedback, and good at handling their obsessions. Those are the two most important traits every creator must foster in themselves.
A creator feeds on energy, and this energy can come from both internal and external sources. Audience feedback is the most important external source, which helps you to assess the quality of your work and provides encouragement. A creator's personal obsessions are their primary internal source of energy, and are essential to producing great work. However, you have to properly channel obsessions, or they can get out of control and become counterproductive.
So how do these two key traits of creators relate to GTD? To find out, here is a quote from GTD, one that I think really gets to the heart of what GTD is all about:
There will always be a large list of actions that you are not doing at any given moment. So how will you decide what to do and what not to do, and feel good about both? The answer is, by trusting your intuition.
– David Allen
As you can see, David here is very careful not to put any hard-and-fast rules on which momentary tasks have preference. This is because, at it's core, GTD is a system for minimizing anxiety. The reason GTD is so effective for people is that it first makes them organize their tasks in their totality, then gets them to complete these tasks based on how much anxiety each of them is causing. (Later in the book, Dave does provide some more concrete guidance on task choice, based on things such as "energy level" or by fitting tasks into your longer term vision, but even with this later guidance the primary focus remains on minimizing anxiety.)
The Task Tension system I'm now going to describe has the exact opposite objective: It provides exactly the hard rules for selecting tasks moment-to-moment that is missing in GTD. This is because productivity for creators is precisely about selecting tasks in a smart and methodical way: Creators like us need to select tasks in a manner that leads to regular releases to get the feedback we need and crave (to fully gather external energy) But on the other hand, we also still need to use our obsession to create longer and more thoughtful works, free from the constraints of hard deadlines (to fully harness our internal energy.)
The Task Tension system is a modification of the GTD system I've created in order to make GTD compatible with the Creator mentality. To accomplish this, it modifies GTD in three ways: Enhancing the project list, logging hours on creation tasks & changing the task selection process.
You continue to maintain projects on your project list as with GTD, but any projects you have that involve creating something (called "creation projects" or CPs for short) now have additional rules in the system. A "creation project" could be writing a blog post, shipping a video game, releasing a song. In short, any project you have that involves creating something for an audience falls into this list. Try to avoid distinguishing between different forms of "creation", as each CP worth your time should be equally meaningful to you: Writing your blog post is just as important as carpentering a table or writing an entire book. With Task Tension, all of these are similar forms of creation.
Here are the new rules for managing CPs on your project list:
There must always be exactly four CPs in your project list. You should always make sure you have additional CPs in your "someday" list. That way, you can maintain the four item target by adding a new item every time you complete an existing CP. (Other "non creative" projects such as "Get oil change" are not affected by this limit and continue to coexist on your project list in the regular GTD manner.)
When a new CP is added to your project list, also add a time estimate for how many hours you guess will be required to complete this creation project. Note that this estimate can be very rough, and does not determine when the CP will be completed. This system purposely makes no attempt to quantify the rate at which these hours of work will be completed.
The hour estimates for the CPs in your project list must fall into the following scales, in terms of the number of hours they require:
You must have exactly one creation project in each of these hour ranges, so that your active CPs always vary in their scale. This means that if you want to put a new CP in the list that conflicts in scale with another project, you have to stop yourself and instead find another CP that is shorter/longer and therefore doesn't conflict in scale with your other active CPs.
Whenever you complete a task that is part of a creation project, you will now roughly log the number of hours you spent in a new Tracking Log which is a new tracking sheet that gets added to the other four core GTD lists (e.g. task list, project list, waiting list, someday list.)
The Tracking Log is only used to keep track of four numbers, which is the total number of hours you've spent on each of the four project scales- So it will look something like this:
Note that these four numbers just increase in size indefinitely, and it is perfectly normal to have more hours logged at a scale than the size of that scale. (That just means you've already completed several projects at that scale, and the total time spent on projects at that scale is higher than any individual project's size.)
Also, if you don't fully complete a task but reach another natural breaking point (such as lunch, the end of day, or you simply have run out of steam on that project) it is also fine to log your partial hours early, without completing the task entirely first. This makes it easier to remember how much time you've spent, and also gives you the positive feeling of marking some progress towards your goals.
As promised, Task Tension introduces a new, rigorous moment-to-moment task selection process to GTD. It goes as follows:
If you follow the rules above, you will at all times have four active creative projects happening at all times. This includes a project that is only a few hours in length, all the way up to a HUGE project that consisting of many hundreds of hours. Moreover, you will be spending a roughly equal amount of your time on projects at each scale, releasing many smaller projects for each of the larger projects.
Following the strategy I've described, you will be able to use your obsession to focus for long periods of time on a project, but not to the exclusion of other creative and noncreative tasks, which is essential to remaining healthy: If you just seclude yourself in your basement for a year to create "that one epic project" it will likely not be good for your mental health, and probably won't be good for your artistic vision either (since you are denying yourself the feedback you get from your audience by also working on smaller projects at the same time.)
Task Tension is all about balance: A creator has to maintain balance in their workflow in order to be successful. This balance needs to include feedback on smaller projects from their audience (which will send lots of positive energy your way in the process) but also needs to give the creator space to pursue a larger artistic vision. Hopefully, Task Tension (or some similar system of your own devising, based on these concepts) can help you develop such a positive workflow for your creative ideas!
Since I'm a software developer by trade, I have of course already built my own app that implements Task Tension. However, my current app is highly specific to one person's workflow and would not be usable to other folks yet. However, if it turns out enough other people find the ideas in the post I may generalize my code and release a more universal implementation.
Are you looking for a virtual reality RPG game with lots of depth? You might enjoy Walking Dream, an unusual single-player adventure game targeted for the Oculus Quest in the Summer of 2020! Combining the best of old and new RPG game elements.
In our game engine, we've made a lot of bold (crazy?) technology decisions to create an immersive RPG experience:
That is all.